【问题标题】:Creating Template Links for Pagination in Generic CBV在通用 CBV 中为分页创建模板链接
【发布时间】:2018-01-24 18:27:05
【问题描述】:

我刚开始使用 Django,所以我有很多问题。我已经构建了一个 Mixin 来为 GCBV (ListView) 中的“下一页”和上一页创建分页器模板链接:

class PageLinksMixin:
page_kwarg = 'page'

def _page_urls(self, page_number):
    return "?{pkw}={n}".format(pkw=self.page_kwarg, n=page_number)

def previous_page(self, page):
    if page.has_previous():
        return self._page_urls(page.previous_page_number())
    return None

def next_page(self, page):
    if page.has_next():
        return self._page_urls(page.next_page_number())
    return None

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    page = context.get('page_obj')
    if page is not None:
        context.update({'previous_page_url': self.previous_page(page),
                        'next_page_url': self.next_page(page)})
    return context

似乎一切正常。但我根本看不到函数的某些输入是在哪里创建的。尤其是“page”、“page_number”。 对于 CBV,有必要声明:

page = paginator.page(page_number)

但在 GCBV 中,这显然是不必要的,这意味着该属性是在某处创建的,然后会被继承。 对于 ListView 有一个函数 def paginate_queryset 但在那里页面仅在本地范围而不是全局范围中声明。有人可以向我解释一下吗?我真的很困惑,现在想弄清楚这一点。

这是视图:

class TagList(PageLinksMixin, ListView):
template_name = 'organizer/tag_list.html'
paginate_by = 5
model = Tag

【问题讨论】:

    标签: django django-views


    【解决方案1】:

    Django 泛型ListView 有一个分页器对象,它通过self.get_context_data() 添加到上下文中。这是 Django 源代码:

        def get_context_data(self, **kwargs):
        """
        Get the context for this view.
        """
        queryset = kwargs.pop('object_list', self.object_list)
        page_size = self.get_paginate_by(queryset)
        context_object_name = self.get_context_object_name(queryset)
        if page_size:
            paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
            context = {
                'paginator': paginator,
                'page_obj': page,
                'is_paginated': is_paginated,
                'object_list': queryset
            }
        else:
            context = {
                'paginator': None,
                'page_obj': None,
                'is_paginated': False,
                'object_list': queryset
            }
        if context_object_name is not None:
            context[context_object_name] = queryset
        context.update(kwargs)
        return super(MultipleObjectMixin, self).get_context_data(**context)
    

    在您的 mixin 中,您首先调用 super().get_context_data(),它使用分页器和一个页面对象填充上下文,您将其设置为 page

    page = context.get('page_obj')
    

    最后调用self.previous_page(page) 来获取实际的URL 并将其添加到上下文中。没什么神奇的。

    您也可以从 kwargs 中获取 page_number,从 paginator 实例中获取 page,但由于它已经为您完成,因此上下文中的 page_obj 是最简单的方法。

    【讨论】:

    • 这很有帮助,谢谢。我有一些大脑阻塞,但你能够提供帮助。 Vielen Dank dafür ;)
    • 不客气。 Django Unleashed 是一本好书,但我个人不怎么使用 GCBV,因为它们很容易混淆。如果您不进行太多自定义,它们很好,但如果您确实进行了很多自定义,则很难阅读代码的逻辑,特别是如果您正在处理一个其他开发人员可能需要稍后介入的项目。跨度>
    猜你喜欢
    • 2013-08-13
    • 2012-04-20
    • 2012-08-16
    • 2014-01-29
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    相关资源
    最近更新 更多