问题描述
我在从 page_obj
视图返回的模板中有 ListView
。现在,我想在当前页面之前和之后创建几个页面的链接。因此,我想以这种方式对 page_obj.paginator.page_range
进行切片:page_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]'
。这种情况有解决方法吗?
附言我知道我可以使用整个 page_obj.paginator.page_range
然后使用 if 语句来检查页面是否在所需的范围内,但我认为这有点低效。
解决方法
如我的评论中所述,Django 模板语言不包含正常的 Python 语法。这样做的原因是 Django 旨在将网站的逻辑和设计分开。如果需要执行一些复杂的逻辑,您需要使用模板标签或过滤器。
根据您的需要,包含标签或简单的过滤器都可以使用 page_range
并返回它的切片版本。考虑到我们只能向它传递一个参数,这里的模板过滤器不是很有用,这意味着它不会非常可定制。假设您的分页看起来非常相似,或者您可能会将您使用的模板传递给标签。
首先,您需要在您的应用中创建一个 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 的操作方法。
首先我们声明 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
返回的字典中的所有变量:
{% 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" %}