Используйте django-pagination для генерации ссылки refl = next / prev - PullRequest
4 голосов
/ 15 ноября 2011

Я использую django-pagination , чтобы разбить страницы на страницы. Это прекрасно работает, но я бы хотел настроить

<link rel="prev" href="http://www.example.com/foo/?page=1" />
<link rel="next" href="http://www.example.com/foo/?page=3" />

до <head>, как это рекомендовано Google .

Однако я не нашел способа сделать это (по крайней мере, без дополнительных запросов). Сначала я попытался отредактировать pagination/templates/pagination.html примерно так

{% block extra_head %}
<link rel=... ... />
{% endblock %}

Что, конечно, не сработало (pagination.html включен в тег {% paginate %}, он не расширяет мой layout.html). Затем я попытался изменить свой шаблон для / foo / view примерно так (добавив {% block extra_head %}):

{# foo.html #}
{% extends "layout.html" %}

{% block content %}

{% load pagination_tags %}
{% autopaginate object_list %}
{% paginate %}
{% for obj in object_list %}
  {{ obj }}
{% endfor %}
{% paginate %}

{% endblock %}

{% block extra_head %}
<link rel="prev" href="?page={{ page_obj.previous_page_number }}"/>
{% endblock %}

Но это также не сработает, поскольку переменная page_obj доступна только в области действия {% block content %}. А мог позвонить

{% autopaginate object_list %}

в блоке extra_head, но это будет означать дополнительное попадание в БД (и, возможно, другие побочные эффекты, о которых я не знаю). Есть ли элегантный способ решить эту проблему, в идеале максимально СУХОЙ?

Редактировать: я использую django 1.2.

Ответы [ 2 ]

2 голосов
/ 15 ноября 2011

Вы можете сделать {% autopaginate %} в блоке более высокого уровня, тогда постраничные объекты будут доступны в подблоках.Если у вас нет блока более высокого уровня, это можно сделать в базовом шаблоне:

{% block root %}
...
{% endblock %}

и в расширенном шаблоне:

{% extends "base.html" %}
{% load pagination_tags %}

{% block root %}
    {% autopaginate objects 10 %}
    {{ block.super }}
{% endblock %}

<!-- the rest of your code -->

Теперь, чтобы получить другой рендерингpaginator в голове, вы можете использовать тег with:

{% with we_are_in_head=1 %}
    {% paginate %}
{% endwith %}

И переопределить templates / pagination / pagination.html примерно так:

{% if we_are_in_head %}
    # Your links to next and prev only
{% else %}
    # original code
{% endif %}

Мораль

Это не элегантно, и причина в том, что нумерация страниц должна быть реализована в view. Шаблоны только для рендеринга, шаблоны-теги тоже. Разбиение на страницы делает дополнительные sql-запросы, он также анализирует аргументы из запроса, шаблон совершенно не подходит для этого кода, поэтому необходимо изобрести обходные пути.Эти обходные пути могут сломаться в следующей версии django, они также неуловимы и могут быть случайно нарушены другим разработчиком.

0 голосов
/ 10 июля 2015

Мы можем вызвать autopaginate в виде и затем использовать {% paginate %} как обычно. Вот рецепт, если кто-то все еще сталкивается с описанной проблемой:

from pagination.templatetags.pagination_tags import AutoPaginateNode

def autopaginate(request, context, queryset_var, paginate_by):
    """ It allows us to use paginated objects in different template blocks """
    autopagination = AutoPaginateNode(queryset_var, paginate_by)
    # Inject a request - it's required by `autopagination` function
    context['request'] = request
    autopagination.render(context)
...