zoukankan      html  css  js  c++  java
  • 多对多

    一个表的多个字段外端关联到同一个表

    class Type(models.Model):
        id = models.AutoField('id', primary_key=True)
        name = models.CharField('name', max_length=16, unique=True)
        type = models.CharField('type', max_length=16)
    
    
    class Item(models.Model):
        id = models.AutoField('id', primary_key=True)
        name = models.CharField('name', max_length=32)
        key = models.CharField('key', max_length=32)
        type = models.ManyToManyField(Type)
    
    
    class Rule(models.Model):
        id = models.AutoField('id', primary_key=True)
        name = models.CharField('name', max_length=16)
        arg_1 = models.ForeignKey(Item, on_delete=models.CASCADE,null=True,related_name='arg_1')
        arg_2 = models.ForeignKey(Item, on_delete=models.CASCADE,null=True,related_name='arg_2')
        method = models.CharField('method', max_length=8)
    
    
    class CustomReport(models.Model):
        id = models.AutoField('id', primary_key=True)
        name = models.CharField('name', max_length=16)
        item = models.ManyToManyField(Item)
        rule = models.ForeignKey(Rule, on_delete=models.CASCADE, null=True)
        time_range = models.IntegerField('time_range', null=True)
        period = models.IntegerField('period', null=True)
        create_time = models.DateTimeField('create_time', auto_now_add=True)
        update_time = models.DateTimeField('update_time', auto_now_add=True)
    

    在arg_1,arg_2 设置外键的时候,
    如果只设置models.ForeignKey(Item, on_delete=models.CASCADE
    在迁移模型的时候会报错
    [“ HINT: Add or change a related_name argument to the definition for 'Rule.arg_1 ' or 'Item.relay_to'.
    原因是因为arg_1和arg_2字段指向同一个模型的外键关联名称产生了冲突。
    解决:增加related_name属性,自定义关联名称

    多对多

    Item模型中。
    type = models.ManyToManyField(Type)
    CustomReport模型中
    item = models.ManyToManyField(Item)

    指定多对多字段关联的表模型,在完成迁移之后,在数据库中生成相应的中间表
    CustomReport_item

    Item_type

    orm操作:

    查:

    report.item.all()获取report对象关联的所有item对象,可以根据关系不停的使用嵌套进行查值。

    增:

    增加的是一个列表,列表中可以是对象,也可以是对象的id值,

    1. 添加对象
      report.item.add(item对象) 完成多外键的添加。
    2. 直接使用item赋值
      report.item = Item.objects.all()[0:3]
      这种方式是网上查的,但是我在实际使用时插入不了,提示queryset对象不能插入
    3. 直接使用item的id列表插入
      item_ids 是一个id的列表对象
      report.item.set(item_ids)

    除了使用orm自动生成的中间表,还可以自定义一个中间表,这样就可以方便的进行数据的CRUD了。

    from django.db import models
    class Books(models.Model):
        """ 书籍表 """
        title = models.CharField(max_length=32)  # 书籍名称
        # 外键关联,法1, 不推荐
        # 有啥区别,?字符串和不是字符串的有区别?
        # publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)  # 绑定外键,关联出版社
        # 外键关联,法2, 推荐
        publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)
        # 外键关联, 指点关联字段
        # publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE, to_field='name')  # 关联指定字段
        def __str__(self):
            return self.title
        
    class Author(models.Model):
        """ 作者表 """
        name = models.CharField(max_length=32, unique=True)  # 作者名,并建立唯一约束
        book = models.ManyToManyField(to='Books', through='AuthorToBook')   # 关联书籍表,表示当前表与书籍表建立多对多的关系
    
        def __str__(self):
            return self.name
    
    class AuthorToBook(models.Model):
        """ 第三张表,关联作者和书籍 """
        author = models.ForeignKey('Author')
        book = models.ForeignKey('Books')
        date = models.DateField()
    

    使用定义的中间表来进行增加数据
    AuthorToBook.objects.create(book_id=book_obj.id, author_id=author_obj.id, date='2019-05-21')

    多表关联查询

    查询一对多的关系

    1. django默认每个主表对象都有一个外键的属性,可以通过这个属性查询所有属于主表的字表信息,查询方法主表.字表_set(),返回一个requeryset对象
      tom.Car_set().all()查询tom的所有车信息

    2. 通过在外键中设置related_name属性值即可获取数据
      tom.cars.all()

    3. 通过@property装饰器在model中预定义实现
      tom.all_cars

    多对多的关联对象删除

    通过一个对象(非queryset)来查询所关联的多端对象,然后可以将对象删除,

                gr = GeneralReport.objects.filter(id=report_id).first()
                gr.config.all().delete() #查询所有config对象,删除
                gr.filters.all().delete() #查询所有filters对象,删除
                gr.delete() # 最后删除源数据
                res = {'status': True, 'message': '删除成功'}
    

    https://www.cnblogs.com/lxfpy/p/10890045.html

  • 相关阅读:
    Jdbc 事务
    Spring
    【Java集合的详细研究1】Collections类常用方法总结
    Java Number类
    Java中值类型和引用类型的区别
    Java常量池的理解
    Java重写与重载之间的区别
    Java中Animal b = new Dog();Dog c = new Dog();的区别
    java类构造器的理解
    Javascript history pushState onpopstate方法做AJAX SEO
  • 原文地址:https://www.cnblogs.com/cizao/p/11481902.html
Copyright © 2011-2022 走看看