如何使用Django ORM进行复杂的多表数据操作?

2026-05-22 16:561阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计3015个文字,预计阅读时间需要13分钟。

Django ORM 多表操作相关操作:- ORM 多表数据增删改查- 清空数据- 跨表查询- 聚合查询与Q查询深入理解:- 聚合查询- Q查询

Django ORM 多表操作相关操作:ORM多表添加数据,修改数据,删除数据,清空数据,ORM跨表查询基于对象和双下划线的都在这里,如何聚合查询,F和Q查询又是什么?点进来就get

目录
  • Django ORM 多表操作
    • 表模型
    • 表关系
    • 创建模型
    • 逆向到表模型
    • 插入数据
    • ORM 添加数据(添加外键)
      • 一对多(外键 ForeignKey)
      • 一对一 (OneToOneFeild)
      • 多对多(ManyToManyField):在第三张关系表中新增数据
    • ORM 修改数据
    • ORM 删除和清空数据
    • 跨表查询
      • 基于对象的跨表查询
      • 基于双下划线的跨表查询
    • 聚合查询
      • 示例
    • F查询
    • Q查询

Django ORM 多表操作

表模型
  • 图书表
  • 出版社表
  • 作者表
  • 作者详情表
表关系
  • 一对一:一对一推荐建在查询频率高的一方
  • 一对多:外键字段建在多的一方
  • 多对多:外键字段建在查询频率多的一方,在Django第三张表不需要创建,自动创建

ps:外键字段不需要写表名_id后面的_id,ORM创建的时候自动添加了_id,以及外键以虚拟字段的形式存在

创建模型

'''models.py''' from django.db import models # 书籍表 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=6, decimal_places=2) pub_date = models.DateField() publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') # 出版社表 class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) # 作者表 class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE) # 作者详情表 class AuthorDetail(models.Model): phone_number = models.BigIntegerField() email = models.EmailField()

说明:

  • 1、EmailField 数据类型是邮箱格式,底层继承 CharField,进行了封装,相当于 MySQL 中的 varchar。
  • 2、Django1.1 版本不需要联级删除:on_delete=models.CASCADE,Django2.2 需要。
  • 3、一般不需要设置联级更新.
  • 4、外键在一对多的多中设置:models.ForeignKey("关联类名", on_delete=models.CASCADE)
  • 5、OneToOneField = ForeignKey(...,unique=True)设置一对一。
  • 6、若有模型类存在外键,创建数据时,要先创建外键关联的模型类的数据,不然创建包含外键的模型类的数据时,外键的关联模型类的数据会找不到
逆向到表模型

插入数据

ps:插入几条数据方便操作

ORM 添加数据(添加外键) 一对多(外键 ForeignKey)

方式一: 传对象的形式,返回值的数据类型是对象,书籍对象

步骤:

  • 获取出版社对象
  • 给书籍的出版社属性 pulish 传出版社对象

'''test.py''' import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models pub_obj = models.Publish.objects.filter(pk=1).first() book = models.Book.objects.create(title='水浒传',price='99.9',pub_date='2021-02-07',publish=pub_obj) print(book) # Book object (3) if __name__ == '__main__': main()

方式二: 传对象 id 的形式(常用

一对多中,设置外键属性的类(多的表)中,MySQL 中显示的字段名是:外键属性名_id

返回值的数据类型是对象,书籍对象。

步骤:

  • a. 获取出版社对象的 id
  • b. 给书籍的关联出版社字段 pulish_id 传出版社对象的 id

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models book = models.Book.objects.create(title='西游记',price='88.8',pub_date='2008-08-09',publish_id=1) print(book) 一对一 (OneToOneFeild)

方式一:传对象 id 的形式(常用)

格式:外键属性名_id

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models author = models.Author.objects.create(name='杜甫',age=38,author_detail_id=2) print(author)

方式二:传对象的形式,返回值的数据类型是对象

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models author_detail_obj = models.AuthorDetail.objects.filter(pk=3).first() author = models.Author.objects.create(name='王羲之',age=44,author_detail=author_detail_obj) print(author) 多对多(ManyToManyField):在第三张关系表中新增数据

方式一: 传对象形式,无返回值。

步骤:

  • 获取作者对象
  • 获取书籍对象
  • 给书籍对象的 authors 属性用 add 方法传作者对象

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models '''多对多''' # 获取作者对象 author_obj1 = models.Author.objects.filter(pk=4).first() author_obj2 = models.Author.objects.filter(pk=5).first() # 获取书籍对象 book_obj1 = models.Book.objects.filter(pk=3).first() book_obj2 = models.Book.objects.filter(pk=3).first() # 添加数据 book_obj1.authors.add(author_obj1,author_obj2) book_obj2.authors.add(author_obj2)

方式二: 传对象id形式,无返回值。

步骤:

  • a. 获取作者对象的 id
  • b. 获取书籍对象
  • c. 给书籍对象的 authors 属性用 add 方法传作者对象的 id

import os # Create your tests here. def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models book_obj = models.Book.objects.filter(title='水浒传').first() book_obj.authors.add(1,4)

ORM 修改数据

'''一对多,一对一''' models.Book.objects.filter(pk=1).update(publish_id=2) book_obj = models.Book.objects.filter(pk=1).first() print(book_obj.publish) publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.filter(pk=1).update(publish=publish_obj)

'''多对多''' book_obj.authors.set([3, 2]) book_obj.authors.set([author_obj1, author_obj2]) ORM 删除和清空数据

remove():从关联对象集中移除执行的模型对象

对于 ForeignKey 对象,这个方法仅在 null=True(可以为空)时存在,无返回值

author_obj =models.Author.objects.get(id=1) book_obj = models.Book.objects.get(id=11) author_obj.book_set.remove(book_obj) return HttpResponse("ok")

clear():从关联对象集中移除一切对象,删除关联,不会删除对象

对于 ForeignKey 对象,这个方法仅在 null=True(可以为空)时存在

# 清空三国关联的所有作者 book = models.Book.objects.filter(title="三国演义").first() book.authors.clear() 跨表查询

  • 正向:外键字段在哪,去从该表的角度查另外的表,就是正向
  • 反向:从没有外键表去查另外相关联的表,就是反向

口诀:

  • 正向查询按外键字段
  • 反向查询按表名小写

注意:

正向:属性名 反向:小写类名加 _set 反向查询的时候查询的对象可能有多个的情况加__set,查询的对象只有一个的情况不需要加 基于对象的跨表查询

'''子查询思路''' 1、先查出一个对象 2、基于对象正反查 '''基于对象的跨表查询:正向''' 1.查询三国演义书籍对应的出版社名称 book_obj = models.Book.objects.filter(title='三国演义').first() publish = book_obj.publish print(publish.name) # 南方出版社 2.查询水浒传对应的作者 book_obj = models.Book.objects.filter(title ='水浒传').first() author = book_obj.authors print(author.name) 3.查询李白的手机号 author_obj = models.Author.objects.filter(name='李白').first() author_obj_det = author_obj.author_detail print(author_obj_det.phone_number) '''基于对象的跨表查询:反向''' 4.查询东方出版社出版过的书籍 publish = models.Publish.objects.filter(name='东方出版社').first() books = publish.book_set.all() print(books.first().title) # 西游记 5.查询杜甫写过的书 author = models.Author.objects.filter(name='杜甫').first() books = author.book_set.all() print(books.first().title) 6.查询email是163@qq.com的作者姓名 # 一对一的情况,不需要写_set author_det = models.AuthorDetail.objects.filter(email='163@qq.com').first() author = author_det.author print(author.name) # 李白 基于双下划线的跨表查询

上面的操作类似子查询,将上一个查询结果当作该次查询的条件使用,那么现在演示的跨表操作,就类似sql连表操作(inner join···),是两种不同的查询方法

'''基于双下划线的跨表操作:连表操作''' '''正向''' 1.查询三国演义书籍对应的出版社名称 publish = models.Book.objects.filter(title='三国演义').values('publish__name') print(publish) # <QuerySet [{'publish__name': '南方出版社'}]> 2.查询水浒传对应的作者 author = models.Book.objects.filter(title='水浒传').values('authors__name','authors__age') print(author) 3.查询李白的手机号 auuth_det_obj = models.Author.objects.filter(name='李白').values('author_detail__phone_number') print(auuth_det_obj) '''反向''' 4.查询东方出版社出版过的书籍 book_obj = models.Publish.objects.filter(name='东方出版社').values('book__title') print(book_obj) 5.查询杜甫写过的书 books = models.Author.objects.filter(name='杜甫').values('book__title') print(books) 6.查询email是163@qq.com的作者姓名 author = models.AuthorDetail.objects.filter(email='163@qq.com').values('author__name') print(author) '''一对一的情况''' 7. 查询水浒传对应的作者的电话和电话 author_det = models.Book.objects.filter(title='水浒传').values('authors__author_detail__phone_number','authors__author_detail__email') print(author_det) 聚合查询

  • 聚合函数:Sum,Max,Min,Count,Avg
  • 在Django中使用聚合函数需要导入:from django.db.models import Sum,Max,Min,Min,Count,Avg

注意:

  1. 使用聚合函数查询的时候,建议把聚合结果字段重命名

# 格式:aggregate(别名 = 聚合函数名("属性名称")) models.Book.objects.all().aggregate(AllPrice=Sum('price'))

  1. 聚合查询返回值的数据类型是字典
  2. 聚合函数 aggregate() 是 QuerySet 的一个终止子句, 生成的一个汇总值,相当于 count(),使用 aggregate() 后,数据类型就变为字典,不能再使用 QuerySet 数据类型的一些 API 了
  3. 日期数据类型(DateField)可以用 Max 和 Min
示例

'''聚合查询''' from django.db.models import Avg,Max,Min,Sum,Count '''1、查询所有书籍的总价,平均值,最大值,最小值,个数''' book_totalprice = models.Book.objects.all().aggregate(totalprice = Sum('price'),maxprice = Max('price'),minprice = Min('price'),avgprice = Avg('price'),num = Count('price')) print(book_totalprice) # {'totalprice': Decimal('377.50'), 'maxprice': Decimal('100.00'), 'minprice': Decimal('88.80'), 'avgprice': Decimal('94.375000'), 'num': 4} F查询

F 查询:取出某个字段对应的值

导入:from django.db.models import F

比如F(‘price’)的意思就是取出该书价格的数值

from django.db.models import F # 每本书的价格上调10元 res = models.Book.objects.update(price=F('price')+10) print(res) # 影响的行数:4 # 查询评论数大于阅读数的书籍 res=models.Book.objects.filter(commit_num__gt=F('read_num')) print(res) Q查询

我们知道在filter中写的条件可以以逗号隔开是and的关系,那么或,非得关系如果构造呢?

此时就需要Q函数来帮助我们去构造这些关系:与(&)或(|)非(~)

导入: from django.db.models import Q

from django.db.models import Q 1、查询名字叫三国演义或者价格大于100的书 res = models.Book.objects.filter(Q(title='三国演义')|Q(price__gt=100)) print(res) 2、查询名字叫三国演义并且价格小于100的书 res = models.Book.objects.filter(Q(title='三国演义')&Q(price__lt=100)) print(res) 3、查询名字不是三国演义的书名 res = models.Book.objects.filter(~Q(title='三国演义')) print(res)

本文共计3015个文字,预计阅读时间需要13分钟。

Django ORM 多表操作相关操作:- ORM 多表数据增删改查- 清空数据- 跨表查询- 聚合查询与Q查询深入理解:- 聚合查询- Q查询

Django ORM 多表操作相关操作:ORM多表添加数据,修改数据,删除数据,清空数据,ORM跨表查询基于对象和双下划线的都在这里,如何聚合查询,F和Q查询又是什么?点进来就get

目录
  • Django ORM 多表操作
    • 表模型
    • 表关系
    • 创建模型
    • 逆向到表模型
    • 插入数据
    • ORM 添加数据(添加外键)
      • 一对多(外键 ForeignKey)
      • 一对一 (OneToOneFeild)
      • 多对多(ManyToManyField):在第三张关系表中新增数据
    • ORM 修改数据
    • ORM 删除和清空数据
    • 跨表查询
      • 基于对象的跨表查询
      • 基于双下划线的跨表查询
    • 聚合查询
      • 示例
    • F查询
    • Q查询

Django ORM 多表操作

表模型
  • 图书表
  • 出版社表
  • 作者表
  • 作者详情表
表关系
  • 一对一:一对一推荐建在查询频率高的一方
  • 一对多:外键字段建在多的一方
  • 多对多:外键字段建在查询频率多的一方,在Django第三张表不需要创建,自动创建

ps:外键字段不需要写表名_id后面的_id,ORM创建的时候自动添加了_id,以及外键以虚拟字段的形式存在

创建模型

'''models.py''' from django.db import models # 书籍表 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=6, decimal_places=2) pub_date = models.DateField() publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') # 出版社表 class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) # 作者表 class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE) # 作者详情表 class AuthorDetail(models.Model): phone_number = models.BigIntegerField() email = models.EmailField()

说明:

  • 1、EmailField 数据类型是邮箱格式,底层继承 CharField,进行了封装,相当于 MySQL 中的 varchar。
  • 2、Django1.1 版本不需要联级删除:on_delete=models.CASCADE,Django2.2 需要。
  • 3、一般不需要设置联级更新.
  • 4、外键在一对多的多中设置:models.ForeignKey("关联类名", on_delete=models.CASCADE)
  • 5、OneToOneField = ForeignKey(...,unique=True)设置一对一。
  • 6、若有模型类存在外键,创建数据时,要先创建外键关联的模型类的数据,不然创建包含外键的模型类的数据时,外键的关联模型类的数据会找不到
逆向到表模型

插入数据

ps:插入几条数据方便操作

ORM 添加数据(添加外键) 一对多(外键 ForeignKey)

方式一: 传对象的形式,返回值的数据类型是对象,书籍对象

步骤:

  • 获取出版社对象
  • 给书籍的出版社属性 pulish 传出版社对象

'''test.py''' import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models pub_obj = models.Publish.objects.filter(pk=1).first() book = models.Book.objects.create(title='水浒传',price='99.9',pub_date='2021-02-07',publish=pub_obj) print(book) # Book object (3) if __name__ == '__main__': main()

方式二: 传对象 id 的形式(常用

一对多中,设置外键属性的类(多的表)中,MySQL 中显示的字段名是:外键属性名_id

返回值的数据类型是对象,书籍对象。

步骤:

  • a. 获取出版社对象的 id
  • b. 给书籍的关联出版社字段 pulish_id 传出版社对象的 id

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models book = models.Book.objects.create(title='西游记',price='88.8',pub_date='2008-08-09',publish_id=1) print(book) 一对一 (OneToOneFeild)

方式一:传对象 id 的形式(常用)

格式:外键属性名_id

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models author = models.Author.objects.create(name='杜甫',age=38,author_detail_id=2) print(author)

方式二:传对象的形式,返回值的数据类型是对象

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models author_detail_obj = models.AuthorDetail.objects.filter(pk=3).first() author = models.Author.objects.create(name='王羲之',age=44,author_detail=author_detail_obj) print(author) 多对多(ManyToManyField):在第三张关系表中新增数据

方式一: 传对象形式,无返回值。

步骤:

  • 获取作者对象
  • 获取书籍对象
  • 给书籍对象的 authors 属性用 add 方法传作者对象

import os def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models '''多对多''' # 获取作者对象 author_obj1 = models.Author.objects.filter(pk=4).first() author_obj2 = models.Author.objects.filter(pk=5).first() # 获取书籍对象 book_obj1 = models.Book.objects.filter(pk=3).first() book_obj2 = models.Book.objects.filter(pk=3).first() # 添加数据 book_obj1.authors.add(author_obj1,author_obj2) book_obj2.authors.add(author_obj2)

方式二: 传对象id形式,无返回值。

步骤:

  • a. 获取作者对象的 id
  • b. 获取书籍对象
  • c. 给书籍对象的 authors 属性用 add 方法传作者对象的 id

import os # Create your tests here. def main(): os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoForeignKey.settings') import django django.setup() from app01 import models book_obj = models.Book.objects.filter(title='水浒传').first() book_obj.authors.add(1,4)

ORM 修改数据

'''一对多,一对一''' models.Book.objects.filter(pk=1).update(publish_id=2) book_obj = models.Book.objects.filter(pk=1).first() print(book_obj.publish) publish_obj = models.Publish.objects.filter(pk=1).first() models.Book.objects.filter(pk=1).update(publish=publish_obj)

'''多对多''' book_obj.authors.set([3, 2]) book_obj.authors.set([author_obj1, author_obj2]) ORM 删除和清空数据

remove():从关联对象集中移除执行的模型对象

对于 ForeignKey 对象,这个方法仅在 null=True(可以为空)时存在,无返回值

author_obj =models.Author.objects.get(id=1) book_obj = models.Book.objects.get(id=11) author_obj.book_set.remove(book_obj) return HttpResponse("ok")

clear():从关联对象集中移除一切对象,删除关联,不会删除对象

对于 ForeignKey 对象,这个方法仅在 null=True(可以为空)时存在

# 清空三国关联的所有作者 book = models.Book.objects.filter(title="三国演义").first() book.authors.clear() 跨表查询

  • 正向:外键字段在哪,去从该表的角度查另外的表,就是正向
  • 反向:从没有外键表去查另外相关联的表,就是反向

口诀:

  • 正向查询按外键字段
  • 反向查询按表名小写

注意:

正向:属性名 反向:小写类名加 _set 反向查询的时候查询的对象可能有多个的情况加__set,查询的对象只有一个的情况不需要加 基于对象的跨表查询

'''子查询思路''' 1、先查出一个对象 2、基于对象正反查 '''基于对象的跨表查询:正向''' 1.查询三国演义书籍对应的出版社名称 book_obj = models.Book.objects.filter(title='三国演义').first() publish = book_obj.publish print(publish.name) # 南方出版社 2.查询水浒传对应的作者 book_obj = models.Book.objects.filter(title ='水浒传').first() author = book_obj.authors print(author.name) 3.查询李白的手机号 author_obj = models.Author.objects.filter(name='李白').first() author_obj_det = author_obj.author_detail print(author_obj_det.phone_number) '''基于对象的跨表查询:反向''' 4.查询东方出版社出版过的书籍 publish = models.Publish.objects.filter(name='东方出版社').first() books = publish.book_set.all() print(books.first().title) # 西游记 5.查询杜甫写过的书 author = models.Author.objects.filter(name='杜甫').first() books = author.book_set.all() print(books.first().title) 6.查询email是163@qq.com的作者姓名 # 一对一的情况,不需要写_set author_det = models.AuthorDetail.objects.filter(email='163@qq.com').first() author = author_det.author print(author.name) # 李白 基于双下划线的跨表查询

上面的操作类似子查询,将上一个查询结果当作该次查询的条件使用,那么现在演示的跨表操作,就类似sql连表操作(inner join···),是两种不同的查询方法

'''基于双下划线的跨表操作:连表操作''' '''正向''' 1.查询三国演义书籍对应的出版社名称 publish = models.Book.objects.filter(title='三国演义').values('publish__name') print(publish) # <QuerySet [{'publish__name': '南方出版社'}]> 2.查询水浒传对应的作者 author = models.Book.objects.filter(title='水浒传').values('authors__name','authors__age') print(author) 3.查询李白的手机号 auuth_det_obj = models.Author.objects.filter(name='李白').values('author_detail__phone_number') print(auuth_det_obj) '''反向''' 4.查询东方出版社出版过的书籍 book_obj = models.Publish.objects.filter(name='东方出版社').values('book__title') print(book_obj) 5.查询杜甫写过的书 books = models.Author.objects.filter(name='杜甫').values('book__title') print(books) 6.查询email是163@qq.com的作者姓名 author = models.AuthorDetail.objects.filter(email='163@qq.com').values('author__name') print(author) '''一对一的情况''' 7. 查询水浒传对应的作者的电话和电话 author_det = models.Book.objects.filter(title='水浒传').values('authors__author_detail__phone_number','authors__author_detail__email') print(author_det) 聚合查询

  • 聚合函数:Sum,Max,Min,Count,Avg
  • 在Django中使用聚合函数需要导入:from django.db.models import Sum,Max,Min,Min,Count,Avg

注意:

  1. 使用聚合函数查询的时候,建议把聚合结果字段重命名

# 格式:aggregate(别名 = 聚合函数名("属性名称")) models.Book.objects.all().aggregate(AllPrice=Sum('price'))

  1. 聚合查询返回值的数据类型是字典
  2. 聚合函数 aggregate() 是 QuerySet 的一个终止子句, 生成的一个汇总值,相当于 count(),使用 aggregate() 后,数据类型就变为字典,不能再使用 QuerySet 数据类型的一些 API 了
  3. 日期数据类型(DateField)可以用 Max 和 Min
示例

'''聚合查询''' from django.db.models import Avg,Max,Min,Sum,Count '''1、查询所有书籍的总价,平均值,最大值,最小值,个数''' book_totalprice = models.Book.objects.all().aggregate(totalprice = Sum('price'),maxprice = Max('price'),minprice = Min('price'),avgprice = Avg('price'),num = Count('price')) print(book_totalprice) # {'totalprice': Decimal('377.50'), 'maxprice': Decimal('100.00'), 'minprice': Decimal('88.80'), 'avgprice': Decimal('94.375000'), 'num': 4} F查询

F 查询:取出某个字段对应的值

导入:from django.db.models import F

比如F(‘price’)的意思就是取出该书价格的数值

from django.db.models import F # 每本书的价格上调10元 res = models.Book.objects.update(price=F('price')+10) print(res) # 影响的行数:4 # 查询评论数大于阅读数的书籍 res=models.Book.objects.filter(commit_num__gt=F('read_num')) print(res) Q查询

我们知道在filter中写的条件可以以逗号隔开是and的关系,那么或,非得关系如果构造呢?

此时就需要Q函数来帮助我们去构造这些关系:与(&)或(|)非(~)

导入: from django.db.models import Q

from django.db.models import Q 1、查询名字叫三国演义或者价格大于100的书 res = models.Book.objects.filter(Q(title='三国演义')|Q(price__gt=100)) print(res) 2、查询名字叫三国演义并且价格小于100的书 res = models.Book.objects.filter(Q(title='三国演义')&Q(price__lt=100)) print(res) 3、查询名字不是三国演义的书名 res = models.Book.objects.filter(~Q(title='三国演义')) print(res)