对于同样的事情,这会花费我两个查询吗?

时间:2012-12-27 07:08:24

标签: python django

在我看来,我有这样的正常分页:

paginator = Paginator(book_list, 100)

然后在我看来,我将值传递给我的模板:

return render(request,
...
'paginator': paginator,
...

我的分页有自定义标签,我这样加载:

{% if paginator.count > paginator.per_page %}
    {% load paginator %}
    {% paginator 3 %}
{% endif %}

在我的自定义模板分页标记中,代码中包含以下内容:

def paginator(context, adjacent_pages=2):
    page_obj = context['paginator'].page(context['object_list'].number)
    ...
    'hits': context['paginator'].count,
    ...

一切都按预期工作但是我担心context['paginator'].page(context['object_list'].number),Django是用这个位从DB获取数据还是使用从我的主视图中获取的相同数据?

请指教。感谢。

2 个答案:

答案 0 :(得分:3)

paginator将query_set保持为object_list,在django 1.3.4中,页面方法是

def page(self, number):
    "Returns a Page object for the given 1-based page number."
    number = self.validate_number(number)
    bottom = (number - 1) * self.per_page
    top = bottom + self.per_page
    if top + self.orphans >= self.count:
        top = self.count
    return Page(self.object_list[bottom:top], number, self)

只有与db相关的最后一行,

self.object_list[bottom:top]

object_list只是一个QuerySet,所以如果你多次调用query_set [x:y],是否存在多个查询,就会出现问题。

Django的query_set很懒,如果你不迭代它,就不会触发sql。否则,将有数据库查询。

您可以在django.db.connection.queries中使用检查查询来获取以下代码,

   from django.db import connection

   original = XXXX.objects.filter(...)
   res1 = original[x:y]
   for item in res1:
     print item
   print len(connection.queries), connection.queries[-1]

   res2 = original[x:y]
   for item in res2:
     print item
   print len(connection.queries), connection.queries[-1]

您会发现查询长度会增加。

答案 1 :(得分:1)

我的理解是它只是使用你在主视图中传递它的任何对象。 context['paginator']将返回存储在您传递给上下文的paginator变量中的对象,这是Paginator类的一个实例。

它是否返回数据库的问题仅仅是.page(...)方法。如果调用Paginator.page(...)发出数据库查询,那么它将返回数据库 - 它不会缓存该值。但是,如果该信息已在paginator变量中本地可用,并且.page方法调用了该信息,那么您不会从数据库中重新获取数据。