以下是django中的示例代码。
[案例1]
views.py 的
from sampleapp.models import SampleModel
from django.core.cache import cache
def get_filtered_data():
result = cache.get("result")
# make cache if result not exists
if not result:
result = SampleModel.objects.filter(field_A="foo")
cache.set("result", result)
return render_to_response('template.html', locals(), context_instance=RequestContext(request))
template.html 的
{% for case in result %}
<p>{{ case.field_A}}</p>
{% endfor %}
在这种情况下,在生成缓存后没有生成查询。我通过 django_debug_toolbar 检查了它。
[案例2]
views.py - 添加了一行result = result.order_by('?')
from sampleapp.models import SampleModel
from django.core.cache import cache
def get_filtered_data():
result = cache.get("result")
# make cache if result not exists
if not result:
result = SampleModel.objects.filter(field_A="foo")
cache.set("result", result)
result = result.order_by('?')
return render_to_response('template.html', locals(), context_instance=RequestContext(request))
template.html - 与之前的相同
在这种情况下,即使我缓存了已过滤的查询,它也生成了新的查询。
如何在没有额外查询集的情况下调整随机排序?
制作缓存时我无法放order_by('?')
。
(例如result = SampleModel.objects.filter(field_A="foo").order_by('?')
)
因为它甚至可以缓存随机顺序。
是否与' django queryset是懒惰的有关?
提前致谢。
答案 0 :(得分:7)
.order_by
在数据库级别执行排序。
这是一个例子。我们在var results
中存储了lasy queryset。尚无任何疑问:
results = SampleModel.objects.filter(field_A="foo")
例如,通过迭代来触摸results
:
for r in results: # here query was send to database
# ...
现在,如果我们再次这样做,不会尝试数据库,因为我们已经有了这个确切的查询:
for r in results: # no query send to database
# ...
但是,当您应用.order_by
时,查询将会有所不同。所以,django必须向数据库发送新请求:
for r in results.order_by('?'): # new query was send to database
# ...
<强>解决方案强>
当您在django中执行查询时,您知道,您将从该查询中获取所有元素(即,没有OFFSET和LIMIT),那么您可以在从数据库获取这些元素之后在python中处理这些元素。 / p>
results = list(SampleModel.objects.filter(field_A="foo")) # convert here queryset to list
在该行进行了查询,您拥有results
中的所有元素。
如果您需要获得随机顺序,请立即在python中执行:
from random import shuffle
shuffle(results)
之后,结果将具有随机顺序,而不会将其他查询发送到数据库。