分页和获取参数

Mic*_*ael 12 django

Django 1.11.4

我已经用method =“get”建立了一个搜索表单。搜索表单有很多表单。然后这个输入值作为获取参数在 url 中传输。

问题是如何获得分页。该数据库包含数千个对象。分页是必要的。

这是文档告诉我们的:

https://docs.djangoproject.com/en/1.11/topics/pagination/#using-paginator-in-a-view

它建议如下:

<a href="?page={{ contacts.previous_page_number }}">previous</a>
Run Code Online (Sandbox Code Playgroud)

但这会破坏所有获取参数。

我设法发明的是:

<a href="{{ request.get_full_path }}&page={{ object_list.previous_page_number }}">previous</a>
Run Code Online (Sandbox Code Playgroud)

这有效。但这是愚蠢的。如果向前和向后切换页面,它会产生如下结尾的网址:

page=2&page=3&page=2
Run Code Online (Sandbox Code Playgroud)

我看过谷歌是如何解决这个问题的。在 url 的中间,他们有 start=30。并更改此参数:start=20, start=40。所以,他们换了。

你能帮我理解如何在 Django 中保存获取参数和切换页面吗?当然,以一种优雅的方式。

add*_*oss 9

通用的解决方案是定义一个“自定义模板标签”(一个函数),它保留完整的 URL 但更新你传递给它的 GET 参数。

注册后,您可以在模板中使用此功能:

<a href="?{% query_transform page=contacts.previous_page_number %}">previous</a>
Run Code Online (Sandbox Code Playgroud)

要定义和注册自定义模板标记,请在 python 文件中包含以下代码:

from django import template

register = template.Library()

@register.simple_tag(takes_context=True)
def query_transform(context, **kwargs):
    query = context['request'].GET.copy()
    for k, v in kwargs.items():
        query[k] = v
    return query.urlencode()
Run Code Online (Sandbox Code Playgroud)

*感谢Ben提供 query_transform 代码。这是他的代码中对 python 3 的改编。

为什么这种方法比手动重建 URL 更好:

如果您后来决定需要在 URL 中添加其他参数: 1. 您不必更新模板中的所有链接。2. 您不需要将重构 URL 所需的所有参数都传递给模板。


Sov*_*iut 7

通常,要保留 GET 参数,您只需手动重写它们即可。在很多情况下,必须这样做并不重要。

&page={{page}}&total={{total}}
Run Code Online (Sandbox Code Playgroud)

您可以将其抽象为模板包含或自定义模板标记。

https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/

此外,您可以创建一个字符串过滤器,将 URL 参数作为字符串以及要更改的值的字典。然后,过滤器可以解析参数字符串,更新值,然后将字符串重新组合回 URL 参数。

{{ request.get_full_path | update_param:'page=8' }}
Run Code Online (Sandbox Code Playgroud)