ORM分组与聚合

#########################聚合################################
#查询所有书籍的价格和 字典
ret = Book.objects.all().aggregate(price_sum=Sum("price"))
print(ret)

# 查询所有作者的平均年龄 字典
ret=Author.objects.all().aggregate(sum_age=Avg("age"))
print(ret)

#########################分组###############################
''关键点:
    1.QuerySet对象.annotate()
  2.annotate进行分组统计,按前面values中的字段进行分组
  3.annotate()返回值依然是QuerySet对象
'''
# 查询每一个作者的名称以及出版过的书籍最高价格
ret = Author.objects.values("name").annotate(max_price = Max("book__price")).values("name","max_price")
print(ret)

# 查询每一个出版社的名称以及出过的书籍的平均价格
ret=Publish.objects.values("name").annotate(book_price=Avg("book__price")).values("name","book_price")
print(ret)

# 查询每一本书籍的作者个数
ret=Book.objects.values("title").annotate(count=Count("authors")).values("title","count")
print(ret)

 ########################only、defer、selected_related以及prefetch_related#########################

1.only 与 defer:

result = Author.objects.all().only('id','name') # 只取显示的几列

for item in reuslt:

  print(item.id,item.name,item.age)  # age也可以查询,但是要访问数据库,降低性能。

# result = User.objects.all().defer('id','name') # 不取显示的几列

2. selected_related : 查询关联字段的值 (只能是FK和oneToone)

需求: 打印所有用户姓名以及部门名称
class depart:
title = ....
class User:
name = ...
dp = FK(depart)

# select * from user
# result = models.User.objects.all()
# for item in result:
# print(item.name,item.dp.title) # 每次遍历还要去查询一次

# select * from user left join depart on user.dp_id = depart.id
# dp能连表查询,减少查询次数 只支持 fk和oneToone
# result = models.User.objects.all().selected_related('dp')
# for item in result:
#print(item.name,item.dp.title ) # 这样就不要再去数据库查询,减少查询次数


3. prefetch_related:查询关联字段的值 (可以是FK,oneToone和manyTomany)
示例:
class Depart(models.Model): 5个部门
title = models.CharField(...)
class User(models.Model): 10个用户
name = models.CharField(...)
email = models.CharField(...)
dp = models.FK(Depart)
1.以前的你:11次单表查询
result = User.objects.all()
for item in result:
print(item.name,item.dp.title)
2. seleted_related,主动做连表查询(1次链表)
result = User.objects.all().seleted_related('dp')
for item in result:
print(item.name,item.dp.title)
问题:如果链表多,性能越来越差。
3. prefetch_related:2次单表查询
# select * from user ;
# 通过python代码获取:dp_id = [1,2]
# select * from depart where id in dp_id
result = User.objects.all().prefetch_related('dp')
for item in result:
print(item.name,item.dp.title)







 
。。。。。。。。。。。。。。。。。。
原文地址:https://www.cnblogs.com/fangsheng/p/9747824.html