Django QuerySet

环境

PackageVersion
Django2.2.6
python3.6.0
django-debug-toolbar3.2

理解QuerySet

1.QuerySet 懒加载

  • 对queryset执行filter, slice, 给函数传参,均不会访问数据库
  • queryset加载时,才会访问数据库

2.QuerySet加载

  • Iteration迭代
	for u in User.objects.all():
	    print(u.id)
  • Slicing切片
    queryset可以切片,与数组切片一样。
    注意:
    如果queryset未加载,切片也不会访问数据库(如果切换中有step步长参数,将访问数据库),返回queryset,但是经过切片的queryset不能添加filter,ordering等操作
    如果queryset已经加载,切片后返回list

  • Pickling/Caching

  • repr()

  • len()

  • list()

  • bool() or if 语句

QuerySet有缓存

  • queryset加载时,不可被调用的属性,会被缓存
  • queryset加载时,可被调用的属性,不会被缓存
	from blueapps.account.models import User
	
	# 不触发sql查询
	users = User.objects.all()
	
	# if语句触发sql查询
	if users:
	    print(users[0].id)
	
	users = User.objects.all()
	# 触发一次sql查询
	for _u in users:
	    print(_e.id)
	# 使用缓存
	for _u in users:
	    print(_e.username)

	user = User.objects.get(id='1')
	print(user.get_upper_name()) # 执行数据库查询
	print(user.get_upper_name()) # 再执行一次数据库查询

最佳实践

1. 尽量避免读取全部数据,优先使用exists(), count(), only(), []等函数

	from blueapps.account.models import User
	from django.db import connection
	
	users = User.objects.all()
	# 判断queryser是否存在
	if users.exits(): 
		pirnt(users[0].id)
	
	users = User.objects.all()
	# print(len(users)) 不要使用len()
	print(users.count())
	
	# 只取必要的字段,不要取全部的字段
	users = User.objects.only('username')
	
	# 使用列表表达式替代fou循环
	usernames = [_u.usernmae for _u in users]
	# sql
	# {'sql': 'SELECT "account_user"."id", "account_user"."username" FROM "account_user"','time': '0.002'}
2. 当queryset非常大时,缓存将占据大量内存,应当避免遍历时,产生大量缓存

以时间换空间,使用iterator避免缓存

users = User.objects.all()
for _u in users.iterator():
    print(_u.username)

参考

Django Document
腾讯课堂

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值