一..基于双下划线的跨表查询(join实现)
key:正向查询按字段,反向查询按表明小写
1.一对多跨表查询

1 查询在跨表中可以有两种方式,正向查询就是关键字段在你要搜索的表,没有关键字段就是反向查询 2 跨表查询的显著特点是__双下划线,这道题中在你要找到name,但是Book中没有,通过正向查询关键字段+__来 3 跨表找到name 4 ret=Book.objects.filter(title="python").values("publish__name") 5 # print(ret) 6 ret=Publish.objects.filter(book__title="python").values("name") 7 print(ret) <QuerySet [{'name': '云南出版社'}]>

1 2 查询小瑞出版社出版的所有的书籍的名称 2 这道题中反向解析在出版社开始找,但是条件没有'小瑞',跨表寻找条件, 3 在filter条件先通过反向查询表名小写__+条件找到 4 ret=Book.objects.filter(publish__name="小瑞").values("title") 5 print(ret) 6 ret=Publish.objects.filter(name="小瑞").values("book__title") 7 print(ret)<QuerySet [{'book__title': 'linux'}, {'book__title': 'css'}]>
2.多对多

1 3 查询python这本书籍的作者的年龄 2 在多对多的环境下,和一对多查询一样,是因为django是在太过强大,通过字段和表名小写 3 将多对多关系的三张表统统间接在一起,各取所需, 4 ret=Book.objects.filter(title="linux").values("authors__age") 5 print(ret)<QuerySet [{'authors__age': 18}, {'authors__age': 25}]> 6 ret=Author.objects.filter(book__title="linux").values("age") 7 print(ret)

1 4 查询alex出版过的所有的书籍名称 2 ret=Author.objects.filter(name="alex").values("book__title") 3 print(ret)<QuerySet [{'book__title': 'python5'}, {'book__title': 'linux'}, {'book__title': 'css'}]> 4 ret=Book.objects.filter(authors__name="alex").values("title") 5 print(ret)
3.一对一

1 5 查询alex的手机号 2 ret=Author.objects.filter(name="alex").values("ad__tel") 3 print(ret)<QuerySet [{'ad__tel': 123}]> 4 ret=AuthorDetail.objects.filter(author__name="alex").values("tel") 5 print(ret) 6 6 查询手机号为110的作者的名字 7 ret=AuthorDetail.objects.filter(tel="234").values("author__name") 8 print(ret)<QuerySet [{'author__name': 'egon'}]> 9 ret=Author.objects.filter(ad__tel="234").values("name") 10 print(ret)
聪明的你不难发现只要掌握了查询方式key,都是一样的
4.多个表单连续查询

1 1.查询小瑞出版社出版过的所有书籍的名字以及作者的姓名 2 这里可以通过表之间的关系逐步连成一张大表查询,注意的是连接时 3 是正向还是反向查询 4 ret=Publish.objects.filter(name="小瑞").values("book__title","book__authors__name") 5 print(ret)<QuerySet [{'book__title': 'linux', 'book__authors__name': 'alex'}, {'book__title': 'css', 'book__authors__name': 'alex'}, {'book__title': 'linux', 'book__authors__name': 'egon'}, {'book__title': 'css', 'book__authors__name': 'egon'}]> 6 ret=Author.objects.filter(book__publish__name="小瑞").values("name","book__title") 7 print(ret)
二>
聚合,分组
聚合与分组的区别是,聚合显示的是 aggregate 后面的结果,如
而分组后的结果往往是以all() 分组的话 ,前面不写values().如
一个个queryset对象列表,,需要values 来取出接轨
要是在values为条件分组的话,显示的是values()里面的条件和annotate后面的函数 组成键值对
要是在条件的后面写上了values(),按照具体要求分组,则是会是按你的要求分组
1.聚合

1 #聚合 2 #查询所有作者的平均年龄 3 #聚合分组前一定要引入模块,才会有效 4 from django.db.models import Avg,Max,Sum,Min,Count 5 # 查询坐着的平均年龄 6 # ret=Author.objects.aggregate(Avg("age")) 7 # print(ret){'age__avg': 21.6667} 8 # # 查询所有书籍的个数 9 # ret=Book.objects.aggregate(c=Count("title")) 10 # print(ret) {'c': 4}
2.分组

1 单表分组查询 2 这里的结果就是一个由title 与 c 组成的键值对 3 查询书籍表每一个出版社id以及对应的书籍个数 4 ret=Book.objects.values("title").annotate(c=Count(1)) 5 print(ret)<QuerySet [{'title': 'python5', 'c': 1}, {'title': 'python', 'c': 1}, {'title': 'linux', 'c': 1}, {'title': 'css', 'c': 1}]> 6 # 查询每一个部门的名称以及对应员工的平均薪水 7 ret=Author.objects.values("name").annotate(a=Avg("age")) 8 print(ret)<Que

1 跨表分组查询 2 在跨表分组中,可以在函数中使用跨表,也可以在后面的values()进行取键值对的跨表,和跨表查询一样 3 查询每一个出版社的名称以及对应的书籍平均价格 4 ret=Publish.objects.annotate(c=Avg("book__price")).values("book__title","book__price","email") 5 print(ret)<QuerySet [{'book__title': 'python5', 'book__price': Decimal('100.00'), 'email': '234'}, {'book__title': 'python', 'book__price': Decimal('100.00'), 'email': '234'}, {'book__title': 'linux', 'book__price': Decimal('100.00'), 'email': '123'}, {'book__title': 'css', 'book__price': Decimal('150.00'), 'email': '123'}]> 6 查询每一个作者的名字以及出版的书籍的最高价格 7 ret=Author.objects.values("name").annotate(c=Max("book__price")) 8 print(ret)<QuerySet [{'name': 'alex', 'c': Decimal('150.00')}, {'name': 'egon', 'c': Decimal('150.00')}, {'name': 'zero', 'c': None}]> 9 查询每一个书籍的名称以及对应的作者的个数 10 ret=Book.objects.values("pk").annotate(c=Count("authors")) 11 print(ret) 12 ret=Book.objects.annotate(c=Count("authors")) 13 print(ret) 14 4 查询作者数不止一个的书籍名称以及作者个数 15 ret=Author.objects.annotate(c=Count("book__title")).filter(c__gt=1).values("book__title","c") 16 print(ret) 17 ret=Book.objects.annotate(c=Count("authors__name")).filter(c__gt=1).values("title","c") 18 print(ret)<QuerySet [{'title': 'python5', 'c': 2}, {'title': 'linux', 'c': 2}, {'title': 'css', 'c': 2}]> 19 5 根据一本图书作者数量的多少对查询集 QuerySet进行排序 20 ret=Book.objects.annotate(c=Count("authors__name")).order_by("c") 21 print(ret)<QuerySet [<Book: Book object (2)>, <Book: Book object (1)>, <Book: Book object (4)>, <Book: Book object (3)>]> 22 6 统计每一本以py开头的书籍的名称以及作者个数 23 ret=Book.objects.annotate(c=Count("authors__name")).filter(title__startswith="py").values("title") 24 print(ret)
3.F与Q
F是在filter中,比如说进行两个变量的比较,之类的用F函数
在这之前需要引入函数
from django.db.models import F,Q

1 from django.db.models import F,Q 2 # 查询评论数大于100的所有的书籍名称 3 ret=Book.objects.filter(count_num__gt=1000).values("title") 4 print(ret) 5 # 查询评论数大于2倍点赞数的所有的书籍名称 6 ret=Book.objects.filter(count_num__gt=F("poll_num")) 7 print(ret) 8 # 查询评论数大于2倍点赞数的所有的书籍名称 9 Book.objects.filter(count_num__gt=F("poll_num")*2) 10 ret = Book.objects.filter(Q(price__gt=300)|~Q(comment_count__gt=3000)) 11 print(ret)
Q函数则是进行条件的判断时,比如价格>100或者地址在xxx"",通过比较的函数对比出来
& 和 |或 ~非
ret = Book.objects.filter(Q(price__gt=300)|~Q(comment_count__gt=3000))
print(ret)