Python学习---ORM查询之基于对象的正向/反向/聚合/分组/Q/F查询
ORM查询之基于对象的正向查询与反向查询
对象形式的查询
# 正向查询
1 2 3 4 5 | ret1=models.Book.objects. first () print(ret1.title) print(ret1.price) print(ret1.publisher) print(ret1.publisher. name ) # ret1.publisher是book属性,是Publish对象,非queryset集合 |
# 反向查找
1 2 3 | ret2=models.Publish.objects. last () print(ret2. name ) print(ret2.city) |
#如何拿到与它绑定的Book对象呢?
1 2 | print(ret2.book_set. all ()) # ret2.book_set是一个queryset集合, all ()可以省略 print(ret2.book_set. all (). values ( 'title' ). distinct ()) # 去重 |
ORM查询之基于条件的正向查询与反向查询
单表条件查询[双下划线实现表关联]:使用逗号分隔可以实现and的条件查询
1 2 3 4 5 6 7 | # models.Book.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 # models.Book.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据 # models.Book.objects.exclude(id__notin=[11, 22, 33]) # not in # models.Book.objects.filter(title__contains= "Python" ) # 模糊匹配 # models.Book.objects.filter(name__icontains= "ven" ) # icontains大小写不敏感 # models.Book.objects.filter(id__range=[1,12]) # 范围bettwen and # startswith,istartswith, endswith, iendswith, # 以XXX开始/XXX结束 |
多表条件关联查询[双下划线实现表关联]
一对多[正向查询]: 使用逗号分隔可以实现and的条件查询,filter和values里面均可使用双下划线
1 2 3 4 5 6 | # models.Book.objects.filter(title= 'Python' ,id=5). values ( 'publish__name' ). distinct () # [{ 'publisher__city' : '北京' }] publish__name这里的Book里面的publish属性 # models.Book.objects.filter(publish__id=5). values ( 'title' ). distinct () # Book查找出版社ID=5的书的名字 # models.Book.objects.filter(publish__id=5). values ( 'publish_name' ). distinct () # Book查找出版社ID=5的出版社的名字 |
一对多[反向查询]:使用逗号分隔可以实现and的条件查询,filter和values里面均可使用双下划线
1 2 | # models.Publish.objects.filter(book__title= 'Python' ,book_id=5). values ( 'name' ) . distinct () # [{ 'name' : 'H出版社' }] 查找跟Publish相关的Book的内容,book__title中的book就是Publish的关联表名 |
多对多[正向查询]:使用逗号分隔可以实现and的条件查询
1 2 | # models.Book.objects.filter(title= 'Python' ). values ( 'author__name ' ) . distinct () # models.Book.objects.filter(author__name= 'FTL' ). values ( 'title' ) . distinct () |
多对多[反向查询]:使用逗号分隔可以实现and的条件查询
1 | # models.Author.objects.filter(book__title= 'Python' ). values ( 'name' ) . distinct () |
注意:
1、正向查找的book__title中的book是表名Book
2、正向查找的publish__city或者author__name中的publish,author是book表中绑定的字段【Book里面的属性】
3、一对多和多对多在这里用法没区别
ORM之聚合查询与分组查询
ORM之聚合查询与分组查询
聚合查询: aggregate(*args,**kwargs):可通过filter/Values过滤后聚合
通过对QuerySet进行计算,返回一个聚合值的字典。aggregate()中每一个参数都指定一个包含在字典中的返回值[键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的],即在查询集上生成聚合。
1 2 3 4 5 6 | from django.db.models import Avg , Min , Sum , Max >>> Book.objects. all ().aggregate( Avg ( 'price' )) { 'price__avg' : 34.35} # 系统定义名称 >>> Book.objects. all ().aggregate (average_price= Avg ( 'price' )) { 'average_price' : 34.35} # 自定义了名称 >>> Book.objects.aggregate( Avg ( 'price' ), Max ( 'price' ), Min ( 'price' )) # 其他查询 |
分组查询:annotate(*args,**kwargs):可通过filter/Values过滤后分组
可以通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。
1 2 | from django.db.models import Avg , Min , Sum , Max >>> Book.objects. values ( 'author_name' ).annotate( Sum ( 'price' )) # 根据作者名分组后计算每个作者price |
ORM之 F查询与Q查询
F查询: 只能适用于IntegerFiled 【使用了F查询,默认值是0】
1 2 | from django.db.models import F models.Book.objects. update (num=F( 'num' ) + 100) |
Q查询:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | from django.db.models import Q #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询 q1=models.Book.objects.filter(Q(title__startswith= 'P' )). all () # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。 q2=models.Book.objects.filter(Q( name = 'HHH' )|Q( name = 'FTL' )). all () # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合 Q(title__startswith= 'P' ) | ~Q(pub_date__year=2005) # 4、应用: Book.objects.get( Q(title__startswith= 'P' ) and (Q(pub_date= date (2005, 5, 2)) | Q(pub_date= date (2005, 5, 6))) ) # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。 # 正确: Book.objects.get( Q(pub_date= date (2005, 5, 2)) | Q(pub_date= date (2005, 5, 6)), title__startswith= 'P' ) # 错误: Book.objects.get( question__startswith= 'P' , Q(pub_date= date (2005, 5, 2)) | Q(pub_date= date (2005, 5, 6))) |
Q的信息补充
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # 方式一: 直接用,不能动态实现 models.UserInfo.objects.filter(Q(Q(username=u)&Q(pwd=p))|Q(Q(emial=u)&Q(pwd=p))) # 方式二: 创建Q对象且指定连接connector 【适用于多个元素,因为可用 for 循环,可动态循环】 con = Q() q1 = Q() q1.connector = 'AND' q1.children.append(( 'email' , e)) q1.children.append(( 'password' , p)) # Q(Q(email=e)&Q(pwd=p)) q2 = Q() q2.connector = 'AND' q2.children.append(( 'username' , _value_dict[ 'user' ])) q2.children.append(( 'password' , _value_dict[ 'pwd' ])) # Q(Q(username=u)&Q(pwd=p)) con.add(q1, 'OR' ) con.add(q2, 'OR' ) models.UserInfo.objects.filter(con) |
另外:
1 2 3 4 5 6 | 如果传递过来一个字典:那就可以进行组合搜索: q1 = Q() q2.connector = 'AND' dict = { 'id' : 1 , 'username' : 'hhh' , 'sex' : 'male' , 'age' : 18 } for k,v in dict: q1.children.append((k, v)) # 此时字典里面的所有值进行and组合查询 |
-------------------------------------------
个性签名: 所有的事情到最後都是好的,如果不好,那說明事情還沒有到最後~
本文版权归作者【小a玖拾柒】和【博客园】共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步