查询一般就是使用filter、exclude和get三个方法来实现。在ORM层面,这些查询条件都是使用field+__(双下划线)+condition的方式来实现的。
exact:使用精确的 = 进行查找。如果提供的是一个None,那么在SQL层面就是被解释为NULL,例如
person = Person.objects.get(name__exact="张三");对应的sql语句为:select * from person where name=“张三”
iexact:使用 like 进行查找,例如:people = Person.objects.filter(name__iexact="张三");对应的sql语句为:select * from person where name like “张三”。
contains:判断某个字段是否包含了某个数据。例如:person = Person.objects.filter(name__contains="李");对应的sql语句为:select * from person where name like binary "%李%"。
in:提取给定的field的值是否在给定的容器中。容器可以为list、tuple或者任何一个可以迭代的对象,包括QuerySet对象。如:
person = Person.objects.filter(name__in=["张三","李四","王五"]);sql语句select * from person where name in ("张三","李四","王五")。
gt:某个field的值要大于给定的值。例如:person = Person.objects.filter(age__gt=18)
gte:大于等于。person = Person.objecst.filter(age__gte=18)
lt:小于。person = Person.objects.filter(age__lt=18)
lte:小于等于。person = Person.objects.filter(age__lte=18)
startswith:判断某个值是否是以某个值开始的。大小写敏感。例如:person = Person.objects.filter(name__startswith='张');sql语句为:select * from person where name like '张%'。
istartswith:类似于istartswith,大小写不敏感。
endswith:判断某个字段的值是否以某个值结束。大小写敏感。person = Person.objects.filter(name__endswith='三');sql语句为:select * from person where name like '%三'。
iendswith:类似于endswith,大小写不敏感。
range:判断某个字段的值是否在给定的区间。例如person = Person.objects.filter(age__range=(18,24));sql语句为:select * from person where age between 18 and 24。
date:针对某些date或者datetime类型的字段。可以指定date的范围,并且这个时间过滤还可以使用链式调用。例如:person = Person.objects.filter(birthday__date=date(2019,8,29)),表示查找2019年8月29日出生的人。
year:根据年份进行查找,例如:person = Person.objects.filter(birthday__year=2019);sql语句为:select * from person where birthday between '2018-01-01' and '2019-12-31'。
month:根据月份进行查找。
day:根据日期进行查找。
week_day:根据星期几进行查找,1—7表示 星期天—星期六
time:根据时间进行查找。
isnull:根据值是否为空进行查找。
regex和iregex:大小写敏感和不敏感的正则表达式。
聚合函数是通过aggregate方法来实现的。假设有一张成绩表score.
1、Avg:求平均值,如求成绩的平均分:score_avg = Socre.objects.aggregate(Avg('grade'))。
2、Count:获取指定对象的个数。例如:result = Score.objects.aggregate(Count('id')),表示此成绩表中共有多少条记录。
3、Max和Min:最大值和最小值。例如:result = Socre.objects.aggregate(Max("grade"),Min("grade"));获取最高成绩和最低成绩。
4、Sum:求指定对象的总和,例如:socre_sum = Socre.objects.aggregate(Sum("grade")),求取分数的总和。
1、aggregate:返回使用聚合函数后的字段和值。
2、annotate:在原来字段的基础上添加一个使用了聚合函数的字段,并且在使用聚合函数的时候,会使用当前这个模型的主键进行分组(group by)。
F表达式是用来优化ORM操作数据库的。比如,因为某道题目无正确答案,现在想讲Score表中的所有成绩+2分,如果按照正常的流程,应该是先从数据库中提取所有成绩到python内存中去,然后使用Python代码在每个成绩上+2分,在保存到数据库中。代码如下:
scores = Score.objects.all()
for score in scores:
score.grade += 2
score.save()
如果使用F表达式则为:
from django.db.models import F
Score.objects.update(grade=F('grade')+1000)
Q表达式如果想要实现所有价格高于100元,并且评分达到9以上的图书,那么可以通过以下代码实现:
books = Book.objects.filter(price__gte=100, rating__gte=9)
但是如果想要实现一些复杂的查询语句,比如要查询价格低于10,或者评分利于9分的图书,那么就没办法传递多个条件去实现了。这是就需要Q表达式。代码如下:
from django.db.models import Q
books = Book.objects.filter(Q(price__lte=10) | Q(rating_lte=9))
Q运算还可以进行其它的运算,比如&和~(非)等。