#python #django #django-pagination
Вопрос:
У меня есть page_obj
шаблон, который был возвращен из ListView
представления. Теперь я хотел создать ссылки на несколько страниц до и после текущей страницы. Поэтому я хотел нарезать page_obj.paginator.page_range
так: page_obj.paginator.page_range[page_obj.number-3:page_obj.number 4]
. Это работает в оболочке django, но по какой-то причине, когда я делал это шаблоном, там есть 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, чтобы проверить, находится ли страница в требуемом диапазоне, но я подумал, что это немного неэффективно.
Комментарии:
1. Я не понимаю, зачем вам вообще нужно это делать. Может быть, это то, на что вы смотрите pypi.org/project/django-bootstrap-pagination . Если вы все еще хотите придерживаться своего дела, вы, возможно, можете использовать фильтры шаблонов
2. То, что вы делаете, не работает, потому что язык шаблонов Django не поддерживает весь синтаксис python. Поэтому такие вещи, как индексирование, нарезка и т. Д. не получится. Если вы хотите это сделать, вам нужно будет создать тег шаблона.
3. @danish_wani Я понимаю, что для этого есть пакеты. Но я хотел понять, можно ли разрезать диапазон в шаблонах.
4. @АбдулАзизБаркат, я вижу. Не могли бы вы показать, как это делается? Я не мог найти подходящую метку для этого самостоятельно.
Ответ №1:
Как указано в моем комментарии, язык шаблонов 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
вы хотите написать свои теги. В качестве справки вы можете прочитать инструкции по тегам и фильтрам пользовательских шаблонов в документации.
Во-первых, мы объявляем 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" %}