关于python:Django中基于日期的通用视图的分页

Pagination of Date-Based Generic Views in Django

我有一个很简单的问题。我想在django站点上创建一些基于日期的通用视图,但我也想将它们分页。根据文档,对象_列表视图有page和paginate_by参数,但archive_month视图没有。"正确"的方法是什么?


我创建了一个模板标记来对传递给尚未分页的模板的集合进行基于模板的分页。将以下代码复制到app/templatetags/pagify.py文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from django.template import Library, Node, Variable
from django.core.paginator import Paginator
import settings

register = Library()

class PagifyNode(Node):
    def __init__(self, items, page_size, varname):
        self.items = Variable(items)
        self.page_size = int(page_size)
        self.varname = varname

    def render(self, context):
        pages = Paginator(self.items.resolve(context), self.page_size)
        request = context['request']
        page_num = int(request.GET.get('page', 1))

        context[self.varname] = pages.page(page_num)
        return ''

@register.tag
def pagify(parser, token):
   """
    Usage:

    {% pagify items by page_size as varname %}
   """


    bits = token.contents.split()
    if len(bits) != 6:
        raise TemplateSyntaxError, 'pagify tag takes exactly 5 arguments'
    if bits[2] != 'by':
        raise TemplateSyntaxError, 'second argument to pagify tag must be"by"'
    if bits[4] != 'as':
        raise TemplateSyntaxError, 'fourth argument to pagify tag must be"as"'
    return PagifyNode(bits[1], bits[3], bits[5])

要在模板中使用它(假设我们传递了一个名为items的未分页列表):

1
2
3
4
5
6
{% load pagify %}

{% pagify items by 20 as page %}
{% for item in page %}
    {{ item }}
{% endfor %}

page_size参数(20)也可以是变量。标记自动检测querystring中的page=5变量。如果您需要找到属于页面的分页器(例如,对于页面计数),您可以简单地调用:

1
{{ page.paginator.num_pages }}

基于日期的通用视图没有分页。似乎您不能通过包装它们来添加分页,因为它们返回了呈现的结果。

在这种情况下,我只需写下我自己的观点。您也可以签出通用视图的代码,但在您的情况下,其中大部分代码可能是不需要的。

既然您的问题是一个有效的问题,并且查看代码;我想知道为什么它们没有将查询集生成分离为单独的函数。你可以使用它们,然后按照你的意愿进行渲染。


还有非常好的Django分页插件,它完全独立于底层视图。


我昨天正在处理一个类似的问题,我个人发现最好的解决方案是对所有基于日期的页面使用对象列表通用视图,但传递一个过滤的查询集,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
import datetime, time

def post_archive_month(request, year, month, page=0, template_name='post_archive_month.html', **kwargs):
    # Convert date to numeric format
    date = datetime.date(*time.strptime('%s-%s' % (year, month), '%Y-%b')[:3])
    return list_detail.object_list(
      request,
      queryset = Post.objects.filter(publish__year=date.year, publish__date.month).order_by('-publish',),
      paginate_by = 5,
      page = page,
      template_name = template_name,
      **kwargs)

其中urls.py的内容如下:

1
2
3
url(r'^blog/(?P<year>\d{4})/(?P<month>\w{3})/$',
    view=path.to.generic_view,
    name='archive_month'),

我发现这是解决问题的最简单的方法,而不必使用黑客攻击其他通用视图或编写自定义视图。


Django基于日期的通用视图不支持分页。这张票是2006年开始的。如果需要,可以尝试提供的代码修补程序来实现此功能。我不知道为什么补丁还没有应用到代码库中。