本文主要介绍Django框架querySet的功能分析,通过示例代码进行了非常详细的介绍,对大家的学习或工作有一定的参考价值。有需要的朋友可以参考一下。
可切片
使用Python的切片语法来限制查询集记录的数量。它相当于SQL的LIMIT和OFFSET子句。
Entry.objects.all()[:5] #(限制5)
Entry.objects.all()[5:10] #(偏移5限制5)
不支持负索引(例如Entry.objects.all()[-1])。通常,查询集的切片返回新的查询集3354,其将不执行查询。
可迭代
articleList=模型。Article.objects.all()
对于文章列表中的文章:
打印(文章标题)
惰性查询
查询集不容易执行。——创建查询集不会带来任何数据库访问。您可以保留过滤器一整天,Django不会真正运行查询,直到需要评估查询集。
queryResult=模型。Article.objects.all() #未命中数据库
print(queryResult) #命中数据库
对于queryResult中的文章:
打印(文章标题)#点击数据库
一般来说,只有当你“请求”一个查询集的结果时,你才会从数据库中得到它们。当您真正需要结果时,通过访问数据库来评估查询集。有关计算发生的确切时间,请参见何时计算查询集。
缓存机制
每个查询集都包含一个缓存,以最小化对数据库的访问。理解它是如何工作的将允许你写最有效的代码。
在新创建的查询集中,缓存是空的。第一次评估查询集——并发数据库查询——Django会将查询结果保存到查询集的缓存中,并返回显式请求的结果(例如,如果正在迭代查询集,将返回下一个结果)。该查询集的下一次评估将重用缓存的结果。
请记住这种缓存行为,因为如果您不正确地使用查询集,它会困住您。例如,以下语句创建两个查询集,对它们进行计算,然后丢弃它们:
打印([a .模型中a的标题。Article.objects.all()])
print([a . create _ time for a in models。Article.objects.all()])
这意味着同一个数据库查询将被执行两次,显然会使数据库负载加倍。同时,也有可能两个结果列表不包含相同的数据库记录,因为在两个请求期间可能会添加或删除文章。要避免这个问题,只需保存查询集并重用它:
queryResult=模型。Article.objects.all()
打印([查询结果中a的标题])
print([a . query result中a的a.create _ time)
何时查询集不会被缓存?
查询集不会永远缓存它们的结果。当只评估查询集的一部分时,将检查缓存。如果该部分不在缓存中,则下一个查询返回的记录将不会被缓存。因此,这意味着使用切片或索引来限制查询集不会填满缓存。
例如,重复获取查询集对象中的特定索引,每次都会查询数据库:
queryset=Entry.objects.all()
print queryset[5] #查询数据库
print queryset[5] #再次查询数据库
但是,如果已经评估了所有查询集,将检查缓存:
queryset=Entry.objects.all()
queryset中的条目] #查询数据库
打印查询集[5] #使用缓存
打印查询集[5] #使用缓存
下面是一些其他示例,它们将导致整个查询集被计算并填充到缓存中:
[查询集中条目的条目]
布尔(查询集)
queryset中的条目
列表(查询集)
注意:简单地打印查询集不会填满缓存。
queryResult=模型。Article.objects.all()
print(queryResult) #命中数据库
print(queryResult) #命中数据库
exists()与iterator()方法
存在:
简单的用if语句判断,会完全执行整个queryset,把数据放到缓存里,虽然你并不需要数据!为了避免这种情况,可以使用exists()方法来检查是否有数据:
如果queryResult.exists():
#从“博客文章”限制1中选择(1)作为“a”;args=()
打印(存在.)
迭代器:
当queryset非常大时,缓存就会成为问题。
在处理成千上万条记录时,一次性将其加载到内存中是一种浪费。更糟糕的是,巨大的queryset可能会锁定系统进程,将你的程序带到崩溃的边缘。为了避免在遍历数据时进行queryset缓存,可以使用iterator()方法获取数据,并在处理完数据后将其丢弃。
objs=Book.objects.all()。迭代器()
# iterator()一次只能从数据库中获取少量数据,这样可以节省内存。
对于对象中的对象:
打印(对象标题)
#但是,再次遍历时没有打印,因为迭代器已经遍历了上一次(下一次)到上一次,所以不需要再遍历了。
对于对象中的对象:
打印(对象标题)
当然,使用iterator()方法阻止缓存生成,意味着在遍历同一个queryset时,查询会被重复执行。因此,在使用# use iterator()时要小心,并确保您的代码在操作大型queryset时不会重复执行查询。
总结:
Queryset的缓存用于减少程序对数据库的查询。在正常使用情况下,它将确保仅在需要时才查询数据库。使用exists()和iterator()方法优化程序的内存使用。但是,由于它们不生成queryset缓存,因此可能会导致额外的数据库查询。
这就是本文的全部内容。希望对大家的学习有帮助,支持我们。