0

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

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 是用这个位从数据库中获取数据,还是使用从我的主视图中获取的相同数据?

请指教。谢谢。

4

2 回答 2

3

分页器将query_set保持为object_list,在django 1.3.4中,page方法是

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。否则,会有 db 查询。

您可以在 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]

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

于 2012-12-27T08:07:01.510 回答
1

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

它是否回到数据库的问题只是关于.page(...)方法。如果调用Paginator.page(...)发出一个数据库查询,那么它将返回到数据库——它不会缓存该值。但是,如果该信息已经在paginator变量中本地可用并且这就是该.page方法调用的内容,那么您就不会从数据库中重新获取数据。

于 2012-12-27T07:37:47.537 回答