模型层之聚合查询,分组查询,F与Q查询
今日概要
今日内容详细
聚合查询
聚合函数:Max Min Sum Count Avg
在ORM中支持单独使用聚合函数 配合关键字aggregate使用
import os
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoday07Library.settings')
import django
django.setup()
from app01 import models
# 聚合函数需要导模块才可以使用
from django.db.models import Max, Min, Sum, Count, Avg
# 想单独用聚合函数需要关键字aggregate
res = models.Book.objects.aggregate(最大价格=Max('price'), 最小价格=Min('price'), 合计价格=Sum('price'), 平均价格=Avg('price'), 总共几本书=Count('pk'))
print(res)
main()
分组查询
"""
如果执行orm分组查询报错 并且有关键字sql_mode strict mode
移除sql_mode中的only_full_group_by
"""
# 统计每一本书的作者个数
# res = models.Book.objects.annotate(author_num=Count('author__pk')).values('title', 'author_num')
# print(res)
# 统计出每个出版社卖的最便宜的书的价格
# res = models.Publish.objects.annotate(最便宜的书价格为=Min('book__price')).values('name', '最便宜的书价格为')
# print(res)
# 统计不止一个作者的图书
# 1.先统计每本书的作者个数
# res = models.Book.objects.annotate(author_num=Count('author__pk')).values('title', 'author_num')
# print(res)
# 2.再统计出作者大于1的数据
# res = models.Book.objects.annotate(author_num=Count('author__pk')).filter(author_num__gt=1).values('title', 'author_num')
# print(res)
# 查询每个作者出的书的总价格
# res = models.Author.objects.annotate(出的书的总价格=Sum('book__price'), book_num=Count('book__pk')).values('name', '出的书的总价格', 'book_num')
# print(res)
"""
models.表名.objects.annotate() 按照表分组
models.表名.objects.values('字段名').annotate() 按照valuess里的字段分组
"""
res = models.Book.objects.values('publish_id').annotate(count_pk=Count('pk')).values('publish_id', 'count_pk')
print(res)
F与Q查询
'''
补充知识:
"""后续添加两个字段"""
kucun = models.IntegerField(verbose_name='库存数', default=1000)
maichu = models.IntegerField(verbose_name='卖出数', null=True)
default(默认值)
null=True(允许为空)
'''
F查询与两个新方法
# 1.查询库存数大于卖出数的书籍
'''当查询条件不是明确的 也需要从数据库中获取 就需要使用F查询'''
from django.db.models import F
# res = models.Book.objects.filter(kucun__gt=F('maichu'))
# print(res)
# 2.将所有书的价格涨800
# models.Book.objects.update(price=F('price')+800)
# 3.将所有书的后面加字符串爆款
# 针对字符串的拼接需要两个新方法
from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.update(title=Concat(F('title'), Value('新款')))
# 查询主键是1或者价格大于2000的书籍
res = models.Book.objects.filter(pk=1, price__gt=2000)
print(res) # filter内部默认是and关系,不能用or
from django.db.models import Q
res1 = models.Book.objects.filter(Q(pk=1) | Q(price__gt=2000))
print(res1) # 使用Q包裹起来,内部是可以使用或符号 |是or
res2 = models.Book.objects.filter(~Q(pk=1) | Q(price__gt=2000))
print(res2) # ~是not