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