Django:随机排序(order_by('?'))进行附加查询 [英] Django : random ordering(order_by('?')) makes additional query

查看:798
本文介绍了Django:随机排序(order_by('?'))进行附加查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是django中的示例代码。

Here is sample codes in 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))

模板.html

  {% for case in result %}
  <p>{{ case.field_A}}</p>
  {% endfor %}

在这种情况下,之后没有生成查询已缓存。我通过 django_debug_toolbar 进行了检查。

In this case, there's no generated query after cache made. I checked it by 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 -与上一个相同

在这种情况下,即使我已缓存,它也会生成新查询过滤的查询

In this case, it generated new query even though I cached filtered query.

如何在不使用附加查询集的情况下适应随机排序?

How can I adapt random ordering without additional queryset?


  • 进行缓存时,我不能放置 order_by(’?’)
    (例如 result = SampleModel.objects.filter(field_A = foo)。order_by('?')
    因为它甚至会随机缓存

  • I can't put order_by('?') when making a cache. (e.g. result = SampleModel.objects.filter(field_A="foo").order_by('?')) Because it even caches random order.

它与 django queryset is lazy 相关吗?

预先感谢。

推荐答案

.order_by 在数据库级别执行排序。

.order_by performs sorting at database level.

这里是一个示例。我们在var results 中存储惰性查询集。尚未进行任何查询:

Here is an example. We store lasy queryset in var results. No query has been made yet:

results = SampleModel.objects.filter(field_A="foo")

触摸结果,例如,对其进行迭代:

Touch the results, for example, by iterating it:

for r in results:  # here query was send to database
    # ...

现在,如果我们再次执行此操作,将不会尝试进行数据库操作,因为我们已经有了以下确切的查询:

Now, if we'll do it again, no attempt to database will be made, as we already have this exact query:

for r in results:  # no query send to database
    # ...

但是,当您应用 .order_by 时,查询将有所不同。因此,django必须向数据库发送新请求:

But, when you apply .order_by, the query will be different. So, django has to send new request to database:

for r in results.order_by('?'):  # new query was send to database
    # ...

解决方案

在django中执行查询时,您会知道将从该查询中获取所有元素(即没有OFFSET和LIMIT),然后可以处理这些元素在python中,从数据库中获取它们之后。

When you do the query in django, and you know, that you will get all elements from that query (i.e., no OFFSET and LIMIT), then you can process those elements in python, after you get them from database.

results = list(SampleModel.objects.filter(field_A="foo"))  # convert here queryset to list

在该行进行了查询,所有元素都在<$中c $ c>结果。

At that line query was made and you have all elements in results.

如果需要获取随机订单,请立即在python中执行:

If you need to get random order, do it in python now:

from random import shuffle
shuffle(results)

之后,结果将具有随机顺序,而不会将其他查询发送到数据库。

After that, results will have random order without additional query being send to database.

这篇关于Django:随机排序(order_by('?'))进行附加查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆