使用 django-pagination 生成链接 refl=next/prev

发布于 2024-12-15 07:35:28 字数 1419 浏览 0 评论 0原文

我正在使用 django-pagination 对我的页面进行分页。它效果很好,但我想设置

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

,就像 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 %}范围内。 A 可以调用

{% autopaginate object_list %}

extra_head 块,但这意味着对数据库的额外命中(可能还有我不知道的其他副作用)。有没有一种优雅的方法来解决这个问题,最好是尽可能干燥?

编辑:我正在使用 django 1.2。

I'm using django-pagination to paginate my pages. It works great, but I would like to set up

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

to the <head>, like it is recommended by google .

However I found no way ho to do this (without extra queries at least). First I tried to edit the pagination/templates/pagination.html with something like this

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

Which of course did not work (pagination.html is included by the {% paginate %} tag, it does not extend my layout.html). Next, I tried to modify my template for /foo/ view to something like this (adding the {% 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 %}

But this won't work either, as the page_obj variable is only available in scope of {% block content %}. A could call

{% autopaginate object_list %}

in the extra_head block, but that will mean an extra hit to the db (and possibly other side effects that I'm not aware of). Is there an elegant way to solve this, ideally as DRY as possible?

Edit: I'm using django 1.2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

恰似旧人归 2024-12-22 07:35:28

您可以在较高级别的块中执行 {% autopaginate %} ,然后分页对象将在子块中可用。如果您没有更高级别的块,则可以在基本模板中执行此操作:

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

在扩展模板中:

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

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

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

现在,要在 head 中获得分页器的不同呈现,您可以使用 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 %}

道德

这并不优雅,原因是分页应该在视图中实现。 模板仅用于渲染,模板标签也是如此。分页会产生额外的 sql 查询,它还会解析请求中的参数,模板对于此代码来说是完全错误的位置,因此必须发明解决方法。这些解决方法可能会在 django 的下一个版本中崩溃,它们也很微妙,可能会被其他开发人员意外破坏。

You can do {% autopaginate %} in higher-level block, then paginated objects will be available in sub-blocks. If you don't have higher level block it is possible to do this in base template:

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

And in extended template:

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

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

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

Now, to get a different rendering of paginator in head, you can make use of the with tag:

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

And override templates/pagination/pagination.html with something like this:

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

A moral

This is not elegant and the reason is that pagination should be implemented in the view. Templates are for rendering only, template-tags too. Pagination makes extra sql queries, it also parses arguments from request, template is totally wrong place for this code, so workarounds has to be invented. These workarounds might break on next release of django, they are also subtle and can be accidentally broken by other developer.

蝶舞 2024-12-22 07:35:28

我们可以在视图中调用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)

We can call autopaginate in a view and then use {% paginate %} as usual. Here is a recipe if somebody still face the described problem:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文