多对多

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

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
1240

Item_type
1240

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')

转载于:https://www.cnblogs.com/0916m/p/11481902.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值