88

I am using django 1.2 and going from one view to another using the urlresolvers reverse method.

url = reverse(viewOne)

and I want to pass a get parameter, for example

name = 'joe'

so that in the viewOne if I do

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

I will get

joe

how do I do that ?

Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90
yossi
  • 12,945
  • 28
  • 84
  • 110
  • 4
    Take a look at [that answer](http://stackoverflow.com/a/5341769/301373) that gives a rather nice way to do this kind of thing. – sberder Sep 26 '12 at 03:07
  • 1
    I created a feature request: https://code.djangoproject.com/ticket/25582 – guettli Oct 21 '15 at 09:06

4 Answers4

162

GET parameters have nothing to do with the URL as returned by reverse. Just add it on at the end:

url = "%s?name=joe" % reverse(viewOne)
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 10
    This works for this example. Since no quoting gets done, this fails if you use values which need to be quoted. – guettli Oct 21 '15 at 08:56
84

A safer and more flexible way:

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

then you can use build_url:

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

which takes same arguments as reverse, but provides an extra keyword argument get where you can put your GET parameters in it as a dictionary.

Amir Ali Akbari
  • 5,973
  • 5
  • 35
  • 47
  • 14
    Note: Django's `django.utils.http.urlencode` function might be preferable since it is a "version of Python’s urllib.urlencode() function that can operate on unicode string": https://docs.djangoproject.com/en/1.10/ref/utils/#django.utils.http.urlencode – Dolan Antenucci Sep 01 '16 at 05:21
  • 1
    I would rename this function to `reverse_with_params()` or something similar. – addmoss May 10 '21 at 10:51
22

This is very similar to Amir's solution but handles lists as well.

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

Example usage:

>>> build_url('member-list', params={'format': 'html', 'sex': ['male', 'female']})
u'/members/?format=html&sex=male&sex=female'
clime
  • 8,695
  • 10
  • 61
  • 82
-2

Sorry for the delayed correction on this.

While both the answers here handles the required task too well, i think just a simple function to urlencode a dictionary is the most flexible way of doing this:

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
  • 411
  • 4
  • 7
  • 1
    This does *not* urlencode the dictionary - there is no handling of URL reserved characters (e.g. `#`, `?`) or any type of percent encoding: https://en.wikipedia.org/wiki/Percent-encoding – jamesc Mar 16 '16 at 13:30