Django 聚合查询 分组查询 F与Q查询

需要导入模块:from django.db.models import Max, Min, Sum, Count, Avg

关键语法:aggregate(聚合结果别名 = 聚合函数(参数))

查询结果:使用聚合函数,从每一个组中获取结果:字典

注意点:

1 聚合函数必须在分组之后才能使用

2 没有分组,即默认整体就是一组

3 查询结果为 普通字典

"""
    聚合查询通常情况下都是配合分组一起使用的
    只要是跟数据库相关的模块
      基本上都在 django.db.models 里面
      上述没有那么应该在 django.db里面
"""
from django.db.models import Max, Min, Sum, Count, Avg
1 所有书的平均价格
res = models.Book.objects.aggregate(Avg('price'))
print(res)
2 上述方法一次性使用
res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Count('pk'), Avg('price'))
print(res)

1 关键字:annotate

2 默认以当前表id 分组,并使用聚合函数在组内进行聚合计算,得到结果作为查询结果中组内的属性

from django.db.models import Max, Min, Sum, Count, Avg
1 统计每一本书的作者个数
res = models.Book.objects.annotate()  # models后面点什么 就是按什么分组
res1 = models.Book.objects.annotate(author_num = Count('authors')).values('title', 'author_num')
res2 = models.Book.objects.annotate(author_num = Count('authors__nid')).values('title', 'author_num')
print(res, res1, res3)
"""
author_num 自己定义的字段 用来存储统计出来的每本书对应的作者个数
"""

2 统计每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price = Min('book__price')).values('name', 'min_price')
print(res)

3 统计不止一个作者的图书
    先按照图书分组 求每一本书对应的作者个数
    过滤出不止一个作者的图书
res = models.Book.objects.annotate(author_num = Count('authors')).filter(author_num__gt = 1).values('title', 'author_num')
print(res)

4 查询每个作者出的书的总价格
res = models.Author.objects.annotate(sum_price = Sum('book__price')).values('name', 'sum_price')
print(res)

5 统计 price大于150元 的书籍的作者个数
res = models.Book.objects.filter(price__gt = 150).annotate(num_authors = Count('authors')).values('title', 'num_authors')
print(res)
F查询
"""
能够帮助你直接获取到表中某个字段对应的数据
"""
from django.db.models import F

1 将所有书籍的价格提升 10 块
models.Book.objects.update(price = F('price') + 10)

2 将 django 书的名称后面加上 ' web' 字
"""
在操作字符类型的数据的时候 F不能够直接做到字符串的拼接
"""
from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.filter(title = "django").update(title = Concat(F('title'), Value(' web')))
Q查询
"""
filter括号内多个参数是and关系
"""
from django.db.models import Q

Q包裹逗号分割 还是and关系
res1 = models.Book.objects.filter(Q(price__lt = 300), Q(price__gt = 400))
print(res1)

| or关系
res2 = models.Book.objects.filter(Q(pub_date__lt = '2020-01-01') | Q(price__gt = 300))
print(res2)

~ not关系
res3 = models.Book.objects.filter( ~ Q(pub_date__lt = '2020-01-01') | Q(price__lt = 200))
print(res3)  # <queryset []>

Q&#x7684;&#x9AD8;&#x9636;&#x7528;&#x6CD5;  &#x80FD;&#x591F;&#x5C06;&#x67E5;&#x8BE2;&#x6761;&#x4EF6;&#x7684;&#x5DE6;&#x8FB9;&#x4E5F;&#x53D8;&#x6210;&#x5B57;&#x7B26;&#x4E32;&#x7684;&#x5F62;&#x5F0F;
&#x63D0;&#x524D;&#x751F;&#x6210; Q &#x5BF9;&#x8C61;&#xFF0C;&#x5E76;&#x4F7F;&#x7528; append&#x65B9;&#x6CD5; &#x6DFB;&#x52A0;&#x6761;&#x4EF6;
q = Q()
q.connector = 'or'
q.children.append(('pub_date__lt', '2020-01-01'))
q.children.append(('price__lt', 200))
res = models.Book.objects.filter(q)  # &#x9ED8;&#x8BA4;&#x662F;and&#x5173;&#x7CFB;
print(res)</queryset>

1 定义字段时,指定参数 choices

2 choices 的值为元组套元组(事先定义好,一般在该表类中定义该字段之前定义)

3 每一个元组存放两个元素,形成一种对应关系

4 往数据库中存值时,该字段的值存为元组第一个元素即可

5 通过 对象.get_字段名_display()获取对应的元组第二个元素值,当没有对应关系时,返回的是它本身

示例:

&#x5B9A;&#x4E49;&#x4E00;&#x4E2A; UserTest &#x8868;
class UserTest(models.Model):
    name = models.CharField(max_length = 64)
    gender_choices = ((1, '&#x7537;'),(2, '&#x5973;'),(3, '&#x5176;&#x4ED6;'))
    gender = models.IntegerField(choices = gender_choices)

&#x540C;&#x6B65;&#x8FC1;&#x79FB;&#x5230;&#x6570;&#x636E;&#x5E93;
python manage.py makemigrations
python manage.py migrate

&#x5728; test.py &#x914D;&#x7F6E;&#x6D4B;&#x8BD5;&#x73AF;&#x5883;
&#x5F55;&#x5165;&#x6570;&#x636E;
models.UserTest.objects.create(name = '&#x5C0F;&#x5FAE;', gender = 1)
models.UserTest.objects.create(name = '&#x5C0F;&#x82AC;', gender = 2)
models.UserTest.objects.create(name = '&#x5C0F;&#x6843;', gender = 3)
models.UserTest.objects.create(name = '&#x5C0F;&#x6708;', gender = 4)

&#x9A8C;&#x8BC1;choices
for user_obj in models.UserTest.objects.all():
    print(user_obj.gender, end=' ')
    print(user_obj.get_gender_display())
'''
1 &#x7537;
2 &#x5973;
3 &#x5176;&#x4ED6;
4 4
'''

Original: https://www.cnblogs.com/huaxiayuyi/p/16715793.html
Author: 娇小赤鸦
Title: Django 聚合查询 分组查询 F与Q查询

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/590994/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球