Django ORM多对多的三种模式
1. 使用默认的ManyToManyField创建第三张表、
- 1. 优势
- 可以使用ORM提供的快捷方法
- add()
- clear()
- set()
- remove()
- all()
- 可以使用ORM提供的快捷方法
- 2. 劣势:
- 不能扩展第三张表

from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32) def __str__(self): return self.title class Author(models.Model): name = models.CharField(max_length=32, verbose_name="作者姓名") books = models.ManyToManyField(to='Book') def __str__(self): return self.name

#!/usr/bin/env python # -*- coding:utf8 -*- import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manytomany_test.settings") import django django.setup() from app01 import models author_obj = models.Author.objects.get(id=1) ret = author_obj.books.all() print(ret) # from app02 import models # # author_obj = models.Author.objects.get(id=1) # ret = author_obj.author2book_set.all().values_list("book__title") # print(ret) # from app03 import models # # author_obj = models.Author.objects.get(id=1) # ret = author_obj.books.all() # print(ret) # 删除第一个作者关联的所有书籍,可以直接操作第三张关系表 # models.Author2Book.objects.filter(author=author_obj).delete()
2. 自己创建第三张关系表
- 1. 优势:
- 可以自己扩展第三章关系表的字段(婚恋网站的男女用户的约会记录)
- 2. 劣势:
- 不能使用ORM提供的快捷方法(查询麻烦,需要跨三张表)

from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32, verbose_name="书名") def __str__(self): return self.title class Author(models.Model): name = models.CharField(max_length=32, verbose_name="作者姓名") def __str__(self): return self.name # 自己创建多对多的第三张表 class Author2Book(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author') class Meta: unique_together = (('book', 'author'), )

#!/usr/bin/env python # -*- coding:utf8 -*- import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manytomany_test.settings") import django django.setup() # from app01 import models # # author_obj = models.Author.objects.get(id=1) # ret = author_obj.books.all() # print(ret) from app02 import models author_obj = models.Author.objects.get(id=1) ret = author_obj.author2book_set.all().values_list("book__title") # 先是外键反向查询, 在是外键正向查询 print(ret) # from app03 import models # # author_obj = models.Author.objects.get(id=1) # ret = author_obj.books.all() # print(ret) # 删除第一个作者关联的所有书籍,可以直接操作第三张关系表 # models.Author2Book.objects.filter(author=author_obj).delete()
3.自己创建第三张表,在ManyToManyField中通过through和through_fields指定表名和字段
- 1. 优势:
- 可以使用ORM提供的部分快捷方法
- all()
- 可以扩展第三张关系表的字段
- 可以使用ORM提供的部分快捷方法

from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32, verbose_name="书名") def __str__(self): return self.title class Author(models.Model): name = models.CharField(max_length=32, verbose_name="作者姓名") books = models.ManyToManyField( to='Book', through='Author2Book', through_fields=('author', 'book') # 这里是有顺序的,在那个表种写关联,那个字段就要写的前面 ) def __str__(self): return self.name # 自己创建多对多的第三张表 class Author2Book(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author') class Meta: unique_together = (('book', 'author'),)

#!/usr/bin/env python # -*- coding:utf8 -*- import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "manytomany_test.settings") import django django.setup() # from app01 import models # # author_obj = models.Author.objects.get(id=1) # ret = author_obj.books.all() # print(ret) # from app02 import models # # author_obj = models.Author.objects.get(id=1) # ret = author_obj.author2book_set.all().values_list("book__title") # 先是外键反向查询, 在是外键正向查询 # print(ret) from app03 import models author_obj = models.Author.objects.get(id=1) ret = author_obj.books.all() # 只可使用多对多关系种的all()方法 print(ret) # 删除第一个作者关联的所有书籍,可以直接操作第三张关系表 models.Author2Book.objects.filter(author=author_obj).delete()