Django之modles 多对多创建第三张表
一.第一种:纯自动创建第三张表
纯自动
class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) authors = models.ManyToManyField(to='Author') class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField()
优点:可以利用双下划线和对象点语法 正向 反向
缺点:第三张表的字段 被限定死了 拓展性极差
二.第二种纯手动创建第三张表
class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() # 纯手动创建第三张表 class Book2Author(models.Model): Book = models.ForeignKey(to='Book') Author = models.ForeignKey(to='Author') # 基于第一种没有办法拓展我们第三张表中的字段 纯自动固定只有我们的Book和Author 拓展性极差 info = models.CharField(max_length=64)
test 测试代码
import os import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_22.settings") import django django.setup() from app01 import models # res = models.Book.objects.filter(pk=1).values('author__name') # print(res) # 基于双下划线反向表名也不行了 book_obj = models.Book.objects.filter(pk=1).first() print(book_obj.author__set.all()) # AttributeError: 'NoneType' object has no attribute 'author__set # 基于对象单向表名小写_set >>>反向结果维多必须加_set # 这种方法也不行 查不了 所学知识没办法查啊
优点:第三张表可以添加其他字段拓展性高
缺点:没办法进行正向 反向 __双下划线 和 对象点语法查询 正向字段没有字段 所以没有办法利用ORM 查询
三.第三种半自动 半手动
全是优点:以后开发基本就是用第三种
class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author')) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() class Book2Author(models.Model): book = models.ForeignKey(to='Book') buthor = models.ForeignKey(to='Author') # 基于第一种没有办法拓展我们第三张表中的字段 纯自动固定只有我们的Book和Author 拓展性极差 info = models.CharField(max_length=64)
图形理解
注意点:
test
res = models.Book.objects.filter(pk=1).values('authors__name') print(res) # <QuerySet [{'authors__name': 'koko'}]> # 有时数据库的原因会将数据卡主 需要手动更新 不然查不到数据
正向 反向 查
# 正向查 # book_obj = models.Book.objects.filter(pk=1).first() # print(book_obj.authors.all()) # <QuerySet [<Author: Author object>]> # 正向按字段 结果为多的.all() 即可 # 反向查 作者为yyy的书籍名称 res = models.Author.objects.filter(name='yyy').values('book__title') print(res) # <QuerySet [{'book__title': '海贼王'}]>