(转) Django的ManyToManyField(多对多)中的through的作用

创建一个经典的多对多关系:一本书可以有多个作者,一个作者可以有多本书(如下)

运行“python manage.py makemigratons"和"python manage.py migrate”进行数据迁移之后,

会生成三张表,一个是book(书籍)表包含id,title两个字段,一个是author(作者表)包含id,name两个字段,这是我们刚刚在models.py文件中创建两个模型,但是有一点需要注意的是在book表里面没有我们创建的authors表,而是多了一个book_authors表,在这张表里面又多了两个字段book_id,author_id,其实这个第三张表就是用来存放书籍和作者之间映射关系的中间表

那么我们如何进行数据的查询呢?

1.一本书的所有作者

  b = Book.objects.get(id=1)  #拿到具体哪本书

  b.author.all()

2.一个作者的所有书籍:

  a = Author.objects.get(id=1)

  a.book_set.all() #反向查询

但是如果我们想要搜集关于这个作者发布某一本书籍的时间额外增加一个字段,或者说与现有的系统集成,这个关系表已经存在了,那对于这样的情形,Django允许指定一个用于管理多对多关系的中间模型,然后就可以把这些额外的字段添加到这个中间模型中,具体的方法就是在ManyToMany字段中指定through参数作为中介的中间模型,修改上models.py:

仔细观察BookAuthor这个类,也就是我们前面讲到的中间模型,同时我们看到在创建中间模型的时候我们创建了两个外键,这两个外键定义了两个模型之间是如何关联到一起的, 所以当创建多对多关系模型的时候提倡使用through参数去指定并创建中间模型,这样比较方便我们进行字段的扩展

那么此时我们又该如何添加和删除多对多关系呢?还能使用和刚刚相同的方法吗?

#  添加作者  ringo
ringo = Author.objects.create(name='Ringo',email='ringo@qq.com')
# 添加作者paul
paul = Author.objects.create(name='Paul',email='paul@qq.com')
# 添加书籍 python book1
book1 = Book.objects.create(title='python book1')
#  给多对多添加值也就是添加多对多关系
m1 = BookAuthor(author=ringo,book=book1)
#  第二种添加方式
m2 = BookAuthor.objects,create(author=paul,book=book1)

当我们使用多对多的中间模型之后,add(),remove(),create()这些方法都会被禁用,所以在创建这种类型的关系的时候唯一的方法就是通过创建中间模型的实例

转载于:https://www.cnblogs.com/linyuhong/p/9640078.html

原文地址:https://www.cnblogs.com/atuotuo/p/14051111.html