web-dev-qa-db-fra.com

Comment ajouter la chaîne de requête actuelle à une URL dans un modèle Django?

Lorsque je charge une page, il existe un lien "sameLink" que je souhaite lui ajouter lequery stringde la page qui le contient.

J'ai l'URL suivante: 

somedomain/reporting/article-by-month?variable1=2008

Comment puis je faire ça?

41
Viktor Apoyan

Pour capturer les QUERY_PARAMS qui faisaient partie de la demande, vous référencez le dict contenant ces paramètres (request.GET) et leur code url afin qu'ils soient acceptables dans le cadre d'un href. request.GET.urlencode renvoie une chaîne ressemblant à ds=&date_published__year=2008 que vous pouvez insérer dans un lien de la page, comme suit:

<a href="sameLink/?{{ request.GET.urlencode }}">
106
DrTyrsa

Si vous enregistrez un modèle tel que suit:

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

vous pouvez modifier la chaîne de requête dans votre modèle:

<a href="{% url 'view_name' %}?{% query_transform request a=5 b=6 %}">

Cela préservera tout ce qui se trouve déjà dans la chaîne de requête et ne fera que mettre à jour les clés que vous spécifiez.

12
Michael

J'ai trouvé que la réponse de @ Michael ne fonctionnait pas vraiment lorsque vous vouliez mettre à jour un paramètre de requête existant.

Ce qui suit a fonctionné pour moi:

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

    return updated.urlencode()
9
Prydie

Après @Prydie (merci!), Je voulais faire la même chose, mais dans Python 3 & Django 1.10, avec l’ajout de la possibilité de supprimer les clés de chaîne de requête et de les modifier. Pour cela, j'utilise ceci:

@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()

Le python 3 bits étant kwargs.items() sur .iteritems()

2
Carl Marshall

Informé par d’autres réponses, mais n’ayant pas besoin de la variable request transmise, ne met à jour que les paramètres existants.

@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 ''
1
Inti

Basé sur la solution de @ Prydie (qui utilise elle-même @ Michael), j'ai construit la balise pour renvoyer l'URL complète au lieu de la chaîne de paramètres.

Mon mon projet/template_tags.py

from Django import template


register = template.Library()


# https://stackoverflow.com/a/24658162/2689986
@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())

Mon settings.py

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            ...
            # loads custom template tags
            'libraries': {
                'mytags': 'config.template_tags',
            }
        },
    },
]

Exemple d'utilisation dans les modèles:

{% load mytags %}
<a href="{% add_query_params request page=2 %}">

Testé avec Python3.6 dans Django1.11.10

0
shad0w_wa1k3r