我有一个非常简单的问题。我想在 Django 站点上创建一些基于日期的通用视图,但我也想对它们进行分页。根据文档, object_list 视图具有 page 和 paginate_by 参数,但 archive_month 视图没有。什么是“正确”的做法?
5 回答
我创建了一个模板标签来对传递给尚未分页的模板的集合进行基于模板的分页。将以下代码复制到app/templatetags/pagify.py
文件中。
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的未分页列表):
{% load pagify %}
{% pagify items by 20 as page %}
{% for item in page %}
{{ item }}
{% endfor %}
page_size 参数(20)也可以是一个变量。该标签会自动检测page=5
查询字符串中的变量。如果您需要获取属于该页面的分页器(例如,对于页数),您可以简单地调用:
{{ page.paginator.num_pages }}
基于日期的通用视图没有分页。似乎您也无法通过包装它们来添加分页,因为它们返回渲染结果。
在这种情况下,我会简单地写下我自己的观点。您也可以查看通用视图的代码,但在您的情况下可能不需要其中的大部分。
由于您的问题是有效的,并查看代码;我想知道为什么他们不将查询集生成分离为单独的函数。您可以使用它们并按照您的意愿进行渲染。
我昨天正在处理一个类似的问题,我发现对我个人来说最好的解决方案是对所有基于日期的页面使用 object_list 通用视图,但传递一个过滤的查询集,如下所示:
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 的内容如下:
url(r'^blog/(?P<year>\d{4})/(?P<month>\w{3})/$',
view=path.to.generic_view,
name='archive_month'),
我发现这是解决问题的最简单方法,无需求助于破解其他通用视图或编写自定义视图。
还有一个优秀的 django-pagination插件,它完全独立于底层视图。
Django 基于日期的通用视图不支持分页。有一张从 2006 年开始的公开票。如果您愿意,可以试用提供的代码补丁来实现此功能。我不确定为什么补丁还没有应用于代码库。