Jak przekazać parametry GET za pomocą odwrotnej wersji urlresolvers django

81

Używam django 1.2 i przechodzę z jednego widoku do drugiego przy użyciu metody odwrotnej urlresolvers.

url = reverse(viewOne)

i chcę na przykład przekazać parametr get

name = 'joe'

tak, że w widoku, jeśli to zrobię

def viewOne(request):
    request.GET['name']

wezmę

joe

jak mogę to zrobić ?

yossi
źródło
4
Spójrz na tę odpowiedź, która daje całkiem przyjemny sposób na zrobienie tego rodzaju rzeczy.
sberder
1
Utworzyłem prośbę o funkcję: code.djangoproject.com/ticket/25582
guettli

Odpowiedzi:

150

Parametry GET nie mają nic wspólnego z adresem URL zwróconym przez reverse. Po prostu dodaj na końcu:

url = "%s?name=joe" % reverse(viewOne)
Daniel Roseman
źródło
8
Działa to w tym przykładzie. Ponieważ żadne cytowanie nie jest wykonywane, nie powiedzie się to, jeśli używasz wartości, które muszą być cytowane.
guettli
75

Bezpieczniejszy i bardziej elastyczny sposób:

import urllib
from django.urls import reverse


def build_url(*args, **kwargs):
    get = kwargs.pop('get', {})
    url = reverse(*args, **kwargs)
    if get:
        url += '?' + urllib.urlencode(get)
    return url

wtedy możesz użyć build_url:

url = build_url('view-name', get={'name': 'joe'})

który przyjmuje te same argumenty co reverse, ale zapewnia dodatkowy argument ze słowa kluczowego, w getktórym możesz umieścić swoje GETparametry w nim jako słownik.

Amir Ali Akbari
źródło
12
Uwaga: django.utils.http.urlencodefunkcja Django może być lepsza, ponieważ jest to "wersja funkcji urllib.urlencode () Pythona, która może działać na łańcuchu znaków Unicode": docs.djangoproject.com/en/1.10/ref/utils/ ...
Dolan Antenucci
18

Jest to bardzo podobne do rozwiązania Amira, ale obsługuje również listy.

from django.core.urlresolvers import reverse
from django.http import QueryDict

def build_url(*args, **kwargs):
    params = kwargs.pop('params', {})
    url = reverse(*args, **kwargs)
    if not params: return url

    qdict = QueryDict('', mutable=True)
    for k, v in params.iteritems():
        if type(v) is list: qdict.setlist(k, v)
        else: qdict[k] = v

    return url + '?' + qdict.urlencode()

Przykładowe użycie:

>>> build_url('member-list', params={'format': 'html', 'sex': ['male', 'female']})
u'/members/?format=html&sex=male&sex=female'
klimat
źródło
Jaki jest sens posiadania sex=male&sex=female? Myślę, że powinno być &sex[]=female&sex[]=female(zwróć uwagę na dodatkowe []), aby być tablicą żądań GET
ziemniaki
3
@ ziemniaki To []jest konwencja PHP.
Jonas Schäfer,
-2

Przepraszamy za opóźnioną korektę w tej sprawie.

Chociaż obie odpowiedzi zbyt dobrze radzą sobie z wymaganym zadaniem, myślę, że zwykła funkcja kodu urlencode do słownika jest najbardziej elastycznym sposobem zrobienia tego:

import urllib

def getify(dic):
    st = ''
    for K, V in dic.items():
        K = urllib.parse.quote(str(K))
        if isinstance(V, list):
            for v in V:
                st += K + '=' + urllib.parse.quote(str(v)) + '&'
        else:
            st += K + '=' + urllib.parse.quote(str(V)) + '&'
    return st.rstrip('&')
Avik Samaddar
źródło
1
Ten sposób nie urlencode słownika - nie ma obsługa URL zastrzeżone znaki (np #, ?) lub dowolnego rodzaju kodowanie procentowe: en.wikipedia.org/wiki/Percent-encoding
jamesc