【问题标题】:Pagination of Date-Based Generic Views in DjangoDjango中基于日期的通用视图的分页
【发布时间】:2010-10-14 18:28:33
【问题描述】:

我有一个非常简单的问题。我想在 Django 网站上制作一些基于日期的通用视图,但我也想对它们进行分页。根据文档, object_list 视图具有 page 和 paginate_by 参数,但 archive_month 视图没有。什么是“正确”的做法?

【问题讨论】:

    标签: python django pagination


    【解决方案1】:

    还有优秀的django-pagination插件,完全独立于底层视图。

    【讨论】:

      【解决方案2】:

      Django 基于日期的通用视图不支持分页。上面有一个open ticket from 2006。如果您愿意,可以试用提供的代码补丁来实现此功能。我不确定为什么补丁还没有应用于代码库。

      【讨论】:

        【解决方案3】:

        我昨天正在处理类似的问题,我发现对我个人来说最好的解决方案是对所有基于日期的页面使用 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'),
        

        我发现这是解决问题的最简单方法,无需破解其他通用视图或编写自定义视图。

        【讨论】:

        • +1 虽然它需要您向 extra_context 添加额外信息以补偿基于日期的视图传递的额外变量(年、月等)。
        【解决方案4】:

        我创建了一个模板标签来对传递给尚未分页的模板的集合进行基于模板的分页。将以下代码复制到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 }}
        

        【讨论】:

          【解决方案5】:

          基于日期的通用视图没有分页。似乎您也无法通过包装它们来添加分页,因为它们会返回渲染结果。

          在这种情况下,我会简单地写下我自己的观点。您也可以查看通用视图的代码,但在您的情况下可能不需要其中的大部分代码。

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

          【讨论】:

          • 是的,这正是我正在寻找的,用于生成基于日期参数的查询集的函数。如果我有,那么我可以只使用 object_list 或 pagination 对象。像现在这样,我想我得写下我自己的观点了。
          • 我自己对 django 的通用视图感到沮丧,并且基本上已经编写了通用视图工厂类型的上帝方法,因此我没有这里提到的限制。
          猜你喜欢
          • 2012-06-09
          • 2011-08-06
          • 2013-04-02
          • 1970-01-01
          • 2012-01-28
          • 2013-06-21
          • 2017-05-08
          • 2011-07-29
          • 2010-12-28
          相关资源
          最近更新 更多