56 votes

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

Quand je charge une page, il y a un lien "sameLink" que je veux y ajouter le chaîne de requête de la page qui le contient.

J'ai l'URL suivante :

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

Comment puis-je faire ça ?

127voto

DrTyrsa Points 14349

Pour capturer les QUERY_PARAMS qui faisaient partie de la requête, vous faites référence au dict qui contient ces paramètres ( request.GET ) et les coder en url pour qu'ils soient acceptables comme partie d'un href. request.GET.urlencode renvoie une chaîne qui ressemble à ds=&date_published__year=2008 que vous pouvez placer dans un lien sur la page comme ceci :

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

20voto

Michael Points 622

Si vous enregistrez un templatetag comme 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 permet de préserver tout ce qui se trouve déjà dans la chaîne de requête et de mettre à jour les clés que vous spécifiez.

20voto

Prydie Points 535

J'ai constaté que la réponse de @Michael ne fonctionnait pas tout à fait 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()

5voto

Carl Marshall Points 129

Suite à @Prydie (merci !) j'ai voulu faire la même chose, mais en Python 3 & Django 1.10, avec l'ajout de la possibilité de dépouiller les clés de querystring ainsi que de les modifier. À cette fin, 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 bit python 3 étant kwargs.items() sur .iteritems()

5voto

Ashish Nitin Patil Points 2054

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

Mon monprojet/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 paramètres.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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X