Django的条件查询:查询函数
exclude
exclude:返回不满足条件的数据
res = Author.objects.exclude(pk=1) print(res) # <QuerySet [<Author: Author object (2)>, <Author: Author object (3)>]>
order_by
1、按照 id 升序排序
res = Author.objects.all().order_by('id') print(res) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>, <Author: Author object (3)>]>
2、按照id降序排序
res = Author.objects.all().order_by('-id') print(res) #<QuerySet [<Author: Author object (3)>, <Author: Author object (2)>, <Author: Author object (1)>]>
条件查询( 判断条件名/模糊查询/范围查询/比较查询 /日期查询)
条件格式:
模型类属性名__条件名=值
表中数据:
# 判断条件名:exact
res = Book.objects.get(id__exact=1) print(res) #西游记
# 模糊查询:
1、包含 contains
res = Book.objects.filter(name__contains='红楼') print(res) # <QuerySet [<Book: 红楼梦>]>
2、以什么开头 starswith
res=AuthorDatail.objects.filter(telephone__startswith='198').values('author__name') print(res)
3、以什么结尾 endswith
res=AuthorDatail.objects.filter(telephone__endswith='12').values('author__name') print(res)
4、以什么开头,不区别大小写istartswith
res=AuthorDatail.objects.filter(telephone__istartswith='198').values('author__name') print(res)
5、以什么结尾,不区别大小写 iendswith
res=AuthorDatail.objects.filter(telephone__iendswith='12').values('author__name') print(res)
# 空查询: 是否为空 isnull
# 查询书名不为空的图书 res = Book.objects.filter(name__isnull=False) print(res) #<QuerySet [<Book: 西游记>, <Book: 红楼梦>, <Book: 三国演义>]>
# 范围查询
1、或 in
# 年龄在十八或40的,或 res = models.UserInfo.object.filter(ageage__in=[18,40]).all() print(res)
2、之间range
# 年龄在十八到40的,之间 res = models.UserInfo.object.filter(age__range=[18,40]).all()
# 比较查询 gt、lt、gte大于等于、lte小于等于
res = models.UserInfo.object.filter(age_gt=38).all() age__gt=1---大于 age__lt=1---小于 age__gte=1---大于等于 age__lte=1---小于等于
# 日期查询:year、month、day、week_day、hour、minute、second对日期时间类型
bpub_date = models.DateTimeField(auto_now=True,auto_now_add=True,null=True) # 查询1980年发表的图书。 list = BookInfo.objects.filter(bpub_date__year=1980) # 查询1980年1月1日后发表的图书。 list = BookInfo.objects.filter(bpub_date__gt=date(1990,1,1))
F对象
# 之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象
# F查询:拿到某个字段在表中具体的值
语法如下:from django.db.models import F
f(属性名)
1.查询卖出数大于库存数的书籍:
from django.db.models import F res = models.Book.objects.filter(maichu__gt=F('kucun')) print(res)
2、将所有书籍的价格提升500块:
from django.db.models import F res = models.Book.objects.update(price=F('price') + 500) print(res)
3、将所有书的名称后面加上 ' 爆款 ' 两个字:
from django.db.models.functions import Concat #拼接字符串 from django.db.models import Value res = models.Book.objects.update(title=Concat(F('title'), Value('爆款'))) print(res) # models.Book.objects.update(title=F('title') + '爆款') # 所有的名称会全部变成空白 """在操作字符类型的数据的时候 F不能够直接做到字符串的拼接"""
Q对象
1、多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字
# 查询阅读量大于20,并且编号小于3的图书 list=BookInfo.objects.filter(bread__gt=20,id__lt=3) 或 list=BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)
2、如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符
语法如下: Q(属性名__运算符=值)
# 查询阅读量大于20的图书 from django.db.models mport Q list = BookInfo.objects.filter(Q(bread__gt=20))
3、Q对象可以使用&、|连接,&表示并且,|表示或
# 查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现 from django.db.models mport Q list = BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3)) # 复杂逻辑:(名字为红楼梦并且价格大于100) 或者 id 大于 2 res = Book.objects.filter((Q(name='红楼梦') & Q(price__gt=100))|Q(nid__gt=2))
4、Q对象前可以使用~操作符,表示非not
# 查询编号不等于3的图书 from django.db.models mport Q list = BookInfo.objects.filter(~Q(pk=3))
5、exclude() 也是取反
# 查询编号不等于3的图书 list = BookInfo.objects.exclude(id=3) list = BookInfo.objects.exclude(id__exact=3)
聚合查询
aggregate是QuerySet 的一个终止子句,用来做聚合查询
1、聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中
注意aggregate的返回值是一个字典类型,格式如下:
{'属性名__聚合类小写':值} # {'bread__sum':3}
select name,price,avg('price') as average_price from book; Book.objects.aggregate(average_price=Avg('price')) ret = Book.objects.all().aggregate(avg_price=Avg('price'), min_price=Min('price')) # 查询图书的总阅读量 from django.db.models import Sum list = BookInfo.objects.aggregate(Sum('bread'))
2、使用count时一般不使用aggregate()过滤器
注意count函数,返回值是一个数字
# 查询图书总数。 list = BookInfo.objects.count()
分组查询
# 分组查询:分组后通常会用聚合,annotate用来分组和聚合的
annotate:
filter 在 annotate 前:表示过滤,where条件
values 在 annotate 前:表示分组的字段,如果不写表示按整个表分组
filter 在 annotate 后:表示 having条件
values 在 annotate后:表示取字段---》只能取分组字段和聚合函数字段
# 分组的目的:把有相同特征的分成一组,分成一组后:Avg,Count,Max,Min,Sum统计总条数,统计平均数,求最大值
# 统计每一本书作者个数---》 res = Book.objects.all().values('id').annotate(author_num=Count("authors")).values('name','author_num') # 统计每一个出版社的最便宜的书---》按出版社 Publish.objects.all().valuse('id').annotate(min_price=Min("book__price")).vlaues('name','min_price') Publish.objects.annotate(MinPrice=Min("book__price")) # 查询每一个书籍的名称,以及对应的作者个数-->按书分 Book.objects.all().values('id').annotate(count_publish=Count("authors")).value('name','count_publish') # 查询每一个以 红开头 书籍的名称,以及对应的作者个数-->按书分 Book.objects.all().filter(name__startswith='红').values('id').annotate(count_publish=Count("authors")).value('name','count_publish') # 查询每一个以 红开头 书籍的名称,以及对应的作者个数大于3的记录-->按书分 Book.objects.all().filter(name__startswith='红')values('id').annotate(count_publish=Count("authors")).filter(count_publish__gt=3).value('name','count_publish')