1、基于双下划线跨表查询(join查询)python
在上一篇中,咱们简单的介绍了基于对象的跨表查询,本章将继续阐述基于双下划线的跨表查询,所用的表格均为上章中所建立的表格。django
##########################基于双下划线的查询:正向查询,按字段,反向查询,按表名#####################函数
一、一对多spa
实例一(正向,用字段):code
# 查询红楼梦的出版社名称 #方式1: ret=Book.objects.filter(title="红楼梦").values("publish__name") print(ret) # <QuerySet [{'publish__name': '北京出版社'}]> # 方式2: res=Publish.objects.filter(book__title="红楼梦").values("name") print(res) #<QuerySet [{'name': '北京出版社'}]>
实例二(反向,用表名):对象
# 查询沙河出版社出版过的书籍名称 #方式1: ret=Publish.objects.filter(name="沙河出版社").values("book__title") print(ret) #<QuerySet [{'book__title': '金品梅2'}, {'book__title': '金品梅3'}]> #方式2: res=Book.objects.filter(publish__name="沙河出版社").values("title") print(res) #<QuerySet [{'title': '金品梅2'}, {'title': '金品梅3'}]>
二、多对多blog
实例一(正向,用字段):ci
# 查询红楼梦全部做者的名字 ret=Book.objects.filter(title="红楼梦").values("authors__name") print(ret) #<QuerySet [{'authors__name': 'alex'}, {'authors__name': 'egon'}]>
实例二(反向,用表名):it
#查询alex出版过的全部书籍 ret=Author.objects.filter(name="alex").values("book__title") print(ret) #<QuerySet [{'book__title': '金品梅2'}, {'book__title': '红楼梦'}]>
三、一对一io
实例一(正向,用字段):
# 查询地址在沙河而且email是123的做者的名字 ret=AuthorDetail.objects.filter(adrr="沙河",email=123).values("author__name") print(ret) #<QuerySet [{'author__name': 'alex'}]>
实例二(反向,用表名):
# 查询alex做者的adrr地址 ret = Author.objects.filter(name="alex").values("authordetail__adrr") print(ret) #<QuerySet [{'authordetail__adrr': '沙河'}]>
实例三(综合实例):
#email以456开头的做者出版过的全部书籍名称以及出版社名称
ret=Book.objects.filter(authors__authordetail__email__startswith="456").values("title","publish__name") print(ret)
总结,在上一章的对象查询中,咱们能够总结为全部的查询是基于一个models对象,而本节中双下划线查询均是基于queryset对象进行的!反向查询使用的表名一样必须为小写。
2、聚合函数(aggregate)
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。若是你想要为聚合值指定一个名称,能够向聚合子句提供它。以下例:
#查询全部书籍的平均价格 # 实例1: ret=Book.objects.all().aggregate(Avg("price")) print(ret) #{'price__avg': 172.66666666666666} # 实例2: res = Book.objects.all().aggregate(avgPrice=Avg("price")) print(res) #{'avgPrice': 172.66666666666666}
若是你但愿生成不止一个聚合,你能够向aggregate()子句中添加另外一个参数。因此,若是你也想知道全部图书价格的最大值和最小值,能够这样查询:
# 查询全部书籍的平均价格、价格最大值、价格最小值 ret = Book.objects.all().aggregate(Avg("price"),Min("price"),Max("price")) print(ret) #{'price__avg': 172.66666666666666, 'price__min': Decimal('123.00'), 'price__max': Decimal('230.00')}
以上实例中须要按照以下方式引入相应的模块方法:
from
django.db.models
import
Avg,
Max
,
Min
3、分组函数(annotate)
annotate()为调用的QuerySet中每个对象都生成一个独立的统计值(统计方法用聚合函数)。
实例1:查询每个出版社出版过的书籍个数
ret=Publish.objects.all().annotate(num=Count("book__title")) #能够理解为每个出版社对象增长一个num字段,该字段值是经过聚合函数联表求得 for pub_obj in ret: print(pub_obj.name,pub_obj.num)
annotate的返回值是querySet,若是不想遍历对象,能够用上values_list,以下:
ret = Publish.objects.all().annotate(num=Count("book__title")).values_list("name","num") print(ret) #<QuerySet [('人民出版社', 0), ('沙河出版社', 2), ('北京出版社', 1)]>
实例2:查询每一本书的做者个数
ret=Book.objects.all().annotate(counts=Count("authors__nid")).values("title","counts") print(ret) #<QuerySet [{'title': '金品梅2', 'counts': 2}, {'title': '金品梅3', 'counts': 2}, {'title': '红楼梦', 'counts': 2}]>