在模板内切片 paginator.page_range

Slicing paginator.page_range inside a template

我在从 ListView 视图返回的模板中有 page_obj。现在,我想在当前页面之前和之后创建指向多个页面的链接。因此,我想这样分割 page_obj.paginator.page_rangepage_obj.paginator.page_range[page_obj.number-3:page_obj.number+4]。这在 django shell 中有效,但出于某种原因,当我将其作为模板时,有一个 Template Syntax Error, Could not parse the remainder: '[page_obj.number-3:page_obj.number+4]' from 'page_obj.paginator.page_range[page_obj.number-3:page_obj.number+4]'。这种情况有解决方法吗?

P.S。我知道我可以使用整个 page_obj.paginator.page_range 然后使用 if 语句来检查页面是否在要求的范围内,但我认为它有点低效。

正如我在评论中所述,Django 模板语言不包含正常的 python 语法。这样做的原因是 Django 旨在分离网站的逻辑和设计。如果需要执行一些复杂的逻辑,您需要使用模板标签或过滤器。

根据您的需要,可以使用包含标记或采用 page_range 和 return 切片版本的简单过滤器。考虑到我们只能将一个参数传递给它,这里的模板过滤器不是很有用,这意味着它不是非常可定制的。假设您的分页看起来非常相似,或者您可能会将使用的模板传递给标签。

首先,您需要在您的应用程序中创建一个 templatetags 子包,然后在其中添加包含您的标签的文件(例如 pagination_tags.py)。布局类似于:

your_app/
    __init__.py
    models.py
    templatetags/
        __init__.py
        pagination_tags.py
    views.py

现在您要在文件中 pagination_tags.py 编写标签。作为参考,您可以阅读文档中 Custom template tags and filters 上的 howto。

首先我们声明register,它是template.Library的一个实例。之后我们将编写我们的模板标签/过滤器。我们将使用 inclusion_tag:

from django import template

register = template.Library()

@register.inclusion_tag('pagination_tag.html')
def show_pagination(page_obj, **kwargs):
    left = kwargs.get('left', 3)
    right = kwargs.get('right', 4)
    pages_iter = page_obj.paginator.page_range[page_obj.number - left:page_obj.number + right]
    template = kwargs.get('template', 'default_pagination_template.html')
    return {**kwargs, 'page_obj': page_obj, 'pages_iter': pages_iter, 'template': template}

现在我们将有一个名为 pagination_tag.html 的简单模板,它将简单地扩展作为关键字参数或 default_pagination_template.html:

传递的模板名称
{% extends template %}

现在在 default_pagination_template.html 或任何其他模板中,我们可以使用字典中的所有变量,我们的函数 show_pagination returns:

{% for page_num in pages_iter %}
    Display page links here, etc.
{% endfor %}

您可以根据需要修改此实现。我也将 default_pagination_template.html 的设计和实现留给你。

现在在您要使用它的模板中,首先我们将加载这些标签。然后我们将使用它们:

{% load pagination_tags %}

...
{% show_pagination page_obj left=5 right=6 template="some_custom_template.html" %}