每一个django模型类,都有一个默认的管理器,objects
QuerySet表示数据库中对象的列表。它可以有0到多个过滤器。过滤器通过给定参数,缩小查询范围(filter)
QuerySet等同于select语句,过滤器是一个限制子句,比如where,比如 limit。
Student.objects.all() # 返回的是queryset
Student.objects.first() # 返回的是对象
Student.objects.last() # 返回的是对象
get(**kwargs)根据给定的条件获取一个对象,如果符合多个,或没有就会报错
fitler(**kwargs)过滤,根据参数提供的条件,获取一个过滤器后的QuerySet,多个条件等同于 select子句
使用and连接,关键字参数的形参必须是模型中的字段名。
In [13]: Student.objects.filter(name='小华').filter(age='19')
Out[13]: <QuerySet [<Student: 小华>]>
In [14]: Student.objects.exclude(age='18')
Out[14]: <QuerySet [<Student: 小华>]>
In [22]: Student.objects.all().order_by('age')
Out[22]: <QuerySet [<Student: 小红>, <Student: 小华>, <Student: pet>]>
In [23]: res = Student.objects.all()
In [24]: res.order_by('age')
Out[24]: <QuerySet [<Student: 小红>, <Student: 小华>, <Student: pet>]>
In [25]: print(res.order_by('age').query)
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`,
`teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`,
`teacher_student`.`time` FROM `teacher_student` ORDER BY `teacher_student`.`age` ASC
In [28]: print(res.order_by('-age','name').query) # 默认asc,-age 代表反向排序
1.数据库数据计算是从0开始的
2.offset X是跳过X个数据,limit Y是选取Y个数据
字典
列表中,只会包含我们指定的字段。如果不指定,包含所有字段。
In [38]: res = Student.objects.values('age')
In [39]: res
Out[39]: <QuerySet [{'age': 19}, {'age': 16}, {'age': 22}]>
In [44]: s = Student.objects.only('name')
In [45]: s
Out[45]: <QuerySet [<Student: 小华>, <Student: 小红>, <Student: pet>]>
In [46]: print(s.query)
SELECT `teacher_student`.`id`, `teacher_student`.`name` FROM `teacher_student`
In [47]: s = Student.objects.defer('name')
In [48]: s
Out[48]: <QuerySet [<Student: 小华>, <Student: 小红>, <Student: pet>]>
In [49]: print(s.query)
SELECT `teacher_student`.`id`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`time` FROM `teacher_student`
In [50]: from django.db.models import Q
In [51]: res = Student.objects.filter(Q(age=16)|Q(age=19))
In [52]: res
Out[52]: <QuerySet [<Student: 小华>, <Student: 小红>]>
In [53]: print(res.query)
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`time` FROM `teacher_student` WHERE (`teacher_student`.`age` = 16 OR `teacher_student`.`age` = 19)
语法都是field__conditon
是 两个下划线
gte (大于等于)
lt (小于)
lte (小于等于)
istartswith (忽略大小写)
iendswith (忽略大小写)
聚合函数
# 计算同学们的年龄平均值
In [65]: from django.db.models import Avg
In [66]: res = Student.objects.aggregate(agg=Avg('age'))
In [67]: res
Out[67]: {'agg': 19.0}
# 找到最大的年龄
In [70]: from django.db.models import Avg, Max, Min, Sum
In [71]: res = Student.objects.aggregate(agg=Max('age'))
In [72]: res
Out[72]: {'agg': 22}
# 找到最小的年龄
In [73]: res = Student.objects.aggregate(agg=Min('age'))
In [74]: res
Out[74]: {'agg': 16}
# 计算同学们的年龄和
In [75]: res = Student.objects.aggregate(agg=Sum('age'))
In [76]: res
Out[76]: {'agg': 57}
分组聚合查询
聚合,分组需要结合 values
, annotate
和聚合方法
看下面的案例
语法:
values(‘分组字段’).annotate(别名=聚合函数(‘字段’)).filter(聚合字段别名条件).values(‘取分组字段’, ‘取聚合字段别名’)
规则:
1.values(…).annotate(…)为分组组合,values控制分组字段,annotate控制聚合字段
2.values可按多个字段分组values(‘分组字段1’, …, ‘分组字段n’),??如果省略代表按操作表的主键分组
3.可以同时对多个字段进行聚合处理annotate(别名1=聚合函数1(‘字段1’), …, 别名n=聚合函数n(‘字段n’))
4.分组后的的filter代表having判断,只对聚合字段进行条件判断,可以省略(对非聚合字段或分组字段进行条件判断代表where判断)
5.取字段值values(…)省略默认取所有分组字段与聚合字段,也可以自主取个别分组字段及聚合字段(取字段的values中出现了非分组或非聚合字段,该字段自动成为分组字段)
# 查询男生女生分别有多少人
In [81]: from django.db.models import Avg, Max, Min, Sum, Count
In [82]: res = Student.objects.values('sex').annotate(Count('sex'))
In [83]: res
Out[83]: <QuerySet [{'sex': 0, 'sex__count': 1}, {'sex': 1, 'sex__count': 2}]>
官方文档https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types
django 中,模型通过特殊的字段进行关系连接