如何将当前查询字符串添加到Django模板中的URL?

Vik*_*yan 46 python django

当我加载页面时,有一个链接"sameLink",我想将其包含在其包含页面的查询字符串中.

我有以下网址:

somedomain/reporting/article-by-month?variable1=2008
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

DrT*_*rsa 112

要捕获作为请求一部分的QUERY_PARAMS,请引用包含这些参数的dict(request.GET)并对它们进行urlencode,以便将它们作为href的一部分接受. request.GET.urlencode返回一个字符串,看起来像ds=&date_published__year=2008你可以放入页面上的链接,如下所示:

<a href="sameLink/?{{ request.GET.urlencode }}">
Run Code Online (Sandbox Code Playgroud)

  • 对于那些刚开始使用的人,请确保在您的设置中启用了django.core.context_processors.request上下文处理器. (19认同)
  • 在以后的 django 版本中它是 `django.template.context_processors.request`,但无论如何以上对我不起作用,返回空字符串 (2认同)

Mic*_*ael 16

如果您注册了如下的模板标签:

@register.simple_tag
def query_transform(request, **kwargs):
    updated = request.GET.copy()
    updated.update(kwargs)
    return updated.urlencode()
Run Code Online (Sandbox Code Playgroud)

您可以修改模板中的查询字符串:

<a href="{% url 'view_name' %}?{% query_transform request a=5 b=6 %}">
Run Code Online (Sandbox Code Playgroud)

这将保留查询字符串中已有的任何内容,只更新您指定的键.

  • 这和@Prydie的答案值得更多关注.我有一个用过滤,排序和分页的用例,没有这个想法,我会被搞砸.我认为这个用例确实非常普遍. (2认同)

Pry*_*die 13

我发现当你想要更新现有的查询参数时,@ Michael的答案并不常用.

以下对我有用:

@register.simple_tag
def query_transform(request, **kwargs):
    updated = request.GET.copy()
    for k, v in kwargs.iteritems():
        updated[k] = v

    return updated.urlencode()
Run Code Online (Sandbox Code Playgroud)

  • 这就是为什么`update()`函数不能正常工作的原因:**"就像标准字典update()方法一样,除了它附加到当前字典项而不是替换它们."**请参阅此处的文档:https://docs.djangoproject.com/en/1.10/ref/request-response/#django.http.QueryDict (2认同)

Car*_*all 5

继@Prydie(谢谢!)之后,我也想做同样的事情,但在 Python 3 和 Django 1.10 中,添加了能够去除查询字符串键以及修改它们的功能。为此,我使用这个:

@register.simple_tag
def query_transform(request, **kwargs):
    updated = request.GET.copy()
    for k, v in kwargs.items():
        if v is not None:
            updated[k] = v
        else:
            updated.pop(k, 0)  # Remove or return 0 - aka, delete safely this key

    return updated.urlencode()
Run Code Online (Sandbox Code Playgroud)

python 3位kwargs.items()结束.iteritems()


Int*_*nti 5

由其他答案告知,但不需要传入request,仅更新现有参数。

@register.simple_tag(takes_context=True)
def querystring(context, **kwargs):
    """
    Creates a URL (containing only the querystring [including "?"]) derived
    from the current URL's querystring, by updating it with the provided
    keyword arguments.

    Example (imagine URL is ``/abc/?gender=male&name=Tim``)::

        {% querystring "name"="Diego" "age"=20 %}
        ?name=Diego&gender=male&age=20
    """
    request = context['request']
    updated = request.GET.copy()
    for k, v in kwargs.items():  # have to iterate over and not use .update as it's a QueryDict not a dict
        updated[k] = v

    return '?{}'.format(updated.urlencode()) if updated else ''
Run Code Online (Sandbox Code Playgroud)


sha*_*k3r 5

基于@Prydie 的解决方案(它本身使用@Michael 的解决方案),我构建了标签以返回完整的 URL 而不仅仅是参数字符串。

我的myproject/template_tags.py

from django import template


register = template.Library()


# /sf/answers/1726071371/
@register.simple_tag
def add_query_params(request, **kwargs):
    """
    Takes a request and generates URL with given kwargs as query parameters
    e.g.
    1. {% add_query_params request key=value %} with request.path=='/ask/'
        => '/ask/?key=value'
    2. {% add_query_params request page=2 %} with request.path=='/ask/?key=value'
        => '/ask/?key=value&page=2'
    3. {% add_query_params request page=5 %} with request.path=='/ask/?page=2'
        => '/ask/?page=5'
    """
    updated = request.GET.copy()
    for k, v in kwargs.items():
        updated[k] = v

    return request.build_absolute_uri('?'+updated.urlencode())
Run Code Online (Sandbox Code Playgroud)

我的设置.py

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            ...
            # loads custom template tags
            'libraries': {
                'mytags': 'config.template_tags',
            }
        },
    },
]
Run Code Online (Sandbox Code Playgroud)

模板中的示例用法

{% load mytags %}
<a href="{% add_query_params request page=2 %}">
Run Code Online (Sandbox Code Playgroud)

在Django1.11.10中用Python3.6测试