Django中ORM中queryset方法详解

1.queryset的含义
queryset是查询集,就是传到服务器上的url里面的查询内容。Django会对查询返回的结果集QuerySet进行缓存,这是为了提高查询效率。也就是说,在你创建一个QuerySet对象的时候,Django并不会立即向数据库发出查询命令,只有在你需要用到这个QuerySet的时候才会这样做。Objects是django实现的mvc中的m,Django中的模型类都有一个objects对象,它是一个Django中定义的QuerySet类型的对象,它包含了模型对象的实例
2.常用的queryset接口
链式调用就是执行一个方法后得到的结果还是这个对象,这样就可以接着在执行对象上执行其他方法
在每个函数(或者方法)的执行结果上可以继续调用同样的方法,因为每个函数的返回值都是它自己, 就是 querySet
2.1支持链式调用的接口
① filter
相当于 select * from table where id =1; 等等
② all
相当于 select * from table;
③ exclude
除此条件之外的,与filter相反
④distinct
用来进行 去重查询
⑤ none
返回空的queryset
⑥reverse
把queryset的结果倒序排列
2.2不支持链式调用的接口
① get
如果查询的结果不存在,则会返回异常。(DoesNotExist)
② create
创建一个model对象
③ get_or_create
get_or_create(defaults=None, **kwargs)
例:user, b = User.objects.get_or_create(u_id=1, name=“张三”, defaults={‘address’:‘上海’})
会返回一个tuple,第一个值是查到或者创建的数据,第二个值是一个布尔,表示是否执行了创建操作。
根据条件查找,如果没查到,就调用create创建
如果查找到的对象超过一个以上,get_or_create 将引发MultipleObjectsReturned。
如果你正在使用MySQL,请确保使用READ COMMITTED 隔离级别而不是默认的REPEATABLE READ,否则你将会遇到get_or_create 引发IntegrityError 但对象在接下来的get() 调用中并不存在的情况
get_or_create() 在Django 视图中的使用。请确保只在POST 请求中使用,除非你有充分的理由。GET 请求不应该对数据有任何影响。而POST 则用于对数据产生影响的请求。更多信息,参见HTTP 细则中的安全的方法。

④ update_or_create
根据条件修改,如果不存在,就调用create创建,原理同上
⑤ count
用于返回queryset有多少条记录
⑥ latset
用于返回最新一条记录, 是需要 Mode Meta 中定义 get latest
by = <用来排序 字段〉
⑦ eraliest
同上,返回最早的一条记录
⑧ first
返回queryset里面第一条记录
⑨ last
同上,返回queryset里面最后一条记录
⑩ exists
返回 True False ,如果只是需要判断 Query Set 是否有数据,用它最合适
例:
entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
print(“Entry contained in queryset”)
11. bulk_create
用来批量插入数据
例:
BlogList = []
for line in f:
title,content = line.split(’****’)
blog = Blog(title=title,content=content)
BlogList.append(blog)
f.close()
Blog.objects.bulk_create(BlogList)
12. in_bluk
批量查询,接收两个参数 id_list 和filed_name rn 通过Post . objects . in_ bulk ( [ 1, 2 , 3] )查询出数据,返回是字典类型,字典类型 key 为查询条件。
例:
content_id_pks = StateObjectRelation.objects.filter(state=int(3), content_type=int(ctype.id)).values_list(‘content_id’, flat=True)
projects = Project.objects.in_bulk(content_id_pks)
13. update
用来根据条件批量更新记录
14. delete
用来根据条件批量删除记录
15. values
返回某个字段的值
例:
title_list= Post.objects filter(category_id=1).values( 'title’ )
#返回的结果包含 dict 的QuerySet ,类似这样 QuerySet [{ ’ title ’: xxx} ,)
16. values_list
和 上面的 value 接口差不多,但是返回的是元组的queryset
例:
<queryset[(‘标题’,)]>
如果只是一个字段的话,可以通过 flat=True 参数, 便于我们后续处理
title_ list =Post objects . filter(category=l) .values_list ( ’ title ', flat=True)
for title in title_list
print(title)
2.3 进阶接口
下面的接口用来提高性能,优化Django项目
(1) defer
把不需要的字段做延迟加载,
例:
posts= Post.objects.all().defer(‘content’)
返回的数据不会包含 content部分
但是当我们需要用到这个字段的时候,再去加载
print(posts[0].content) # 此时会执行数据库查询,获取content
用这个接口容易出现 N+1的情况
在这里插入图片描述
(2) only
同defer接口相反,如果只是想获取所有的title记录,就可以使用only,只获取title的内容,在查询其他值时会产生额外的查询
(3) select_related
就是用来解决外键产生的N+1的问题。
例:
关联表是 owenr
post = Post.objects.all().select_related(‘category’)
for i in post: #产生数据库查询,category数据也会一次性查出来
print(i.category)
这个接口用来解决一对多的关联关系
(4) prefetch_related
针对 多对多的关联关系,避免外键产生的N+1的问题。
例:
关联表是 tag
post = Post.objects.all().prefetch_related(‘tag’)
for i in post: #产生两条查询语句,post 和tag
print(i.tag.all())
2.4 常用的字段查询
(1) contains
包含,用来进行相似查询
例:
Post.objects.filter(content__contains(‘查询条件’))
(2) icontains
同上,只是忽略大小写
(3) exact
精确匹配
(4) in
指定某个集合
例:
Post.objects.filter(id__in([1,2,3]))
(5) gt
大于某个值
(6) get
大于等于某个值
(7) lt
小于某个值
(8) lte
小于等于某个值
(9) startswith
以某个字符串开头
和contains类似
(10) istartswitch
忽略大小写,以某个字符串开头
(11) endswitch
以某个字符串结尾
(12) iendswitch
忽略大小写,以某个字符串结尾
(13) range
范围查询,多用于时间范围
例:
Post.objects.filter(created_time__range=(‘2020-1-1’,‘2022-1-1’))

2.5 进阶查询
① F
F查询——专门取对象中某列值的操作
Django 支持对 F() 对象使用常量和其他 F() 对象的加法,减法,乘法,除法,模和幂运算。
例:
BookInfo.objects.filter(bread__gt=F(‘bcomment’) * 2)

obj = Score.objects.get(stuId=‘12’)
obj.score = F(‘score’) + 1
obj.save()

② Q
Q查询——对对象的复杂查询
主要用来执行 or 或者and等操作
例:
from django.db.models import Q
Post.objects.filter(Q(id=1)|Q(id=3))
Post.objects.filter(Q(id=1) & Q(id=3))

③count
用来做聚合查询 aggregate,获取数量
例:
post_count = Post.objects.aggregate(count(category))

④sum
用来做聚合查询 aggregate,求和
例:
post_sum = Post.objects.aggregate(sum(category))
暂时总结这些吧

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值