Opened 9 years ago

Last modified 4 days ago

#25582 new New feature

Add a way to build URLs with query strings

Reported by: Thomas Güttler Owned by:
Component: Core (URLs) Version: dev
Severity: Normal Keywords:
Cc: Ning, Herbert Fortes, Will Gordon, thenewguy, Carsten Fuchs, Tom Carrick, Sage Abdullah Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

It is a common question on stackoverflow and other places:

How to reverse() to url including GET parameters? Example: .../myview?foo=bar

http://stackoverflow.com/questions/9585491/how-do-i-pass-get-parameters-using-django-urlresolvers-reverse

http://stackoverflow.com/a/27641445/633961

It would be very nice if django could implement a short-cut which provides
this.

It would be useful for python code and template, too.

Change History (21)

comment:1 by Tim Graham, 9 years ago

Summary: reverse() to url including GET parameters: .../myview?foo=barAdd a way to build URLs with query strings
Triage Stage: UnreviewedAccepted
Version: 1.8master

I'm not positive this is something which should live in Django, but if not, we could probably at least add some guidance to the docs about how to go about it. If we do add it, it likely needs a discussion on the DevelopersMailingList to figure out what the API should look like. See also #10941 which asks for a template tag for creating query strings in templates.

comment:2 by Dheerendra Rathor, 9 years ago

Changing anything in {% url %} might create a mess. IMHO creating a new tag which accept a dictionary or list of tuples will practically serve the purpose.

comment:3 by Luke Plant, 9 years ago

As per my comment on #10941:

I think this whole area is solved by

1) For Python code: urlobject ​https://github.com/zacharyvoase/urlobject/ and furl ​https://github.com/gruns/furl
2) For template code: django-spurl - ​https://github.com/j4mie/django-spurl

comment:4 by Thomas Güttler, 9 years ago

@spookylukey for me this ticket is solved by this:

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

It is not difficult. The question is if it will be handy in django core.

comment:5 by Thomas Güttler, 9 years ago

Last edited 9 years ago by Thomas Güttler (previous) (diff)

in reply to:  3 comment:6 by Thomas Güttler, 9 years ago

Replying to spookylukey:

As per my comment on #10941:

I think this whole area is solved by

1) For Python code: urlobject ​https://github.com/zacharyvoase/urlobject/ and furl ​https://github.com/gruns/furl
2) For template code: django-spurl - ​https://github.com/j4mie/django-spurl

I would like to see a solution in django core. I guess the django core developers don't want to pull in a dependency of one of the above packages.

If urlencode() would support unicode, the fix would be trival. But even with the current urlencode() of Python 2.7 the issue can be solved in django core easily.

in reply to:  4 comment:7 by Thomas Güttler, 9 years ago

Replying to guettli:

@spookylukey for me this ticket is solved by this:

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

It is not difficult. The question is if it will be handy in django core.

Unfortunatley urlencode(get) fails if the dictionary get contains unicode.
Related: http://stackoverflow.com/questions/6480723/urllib-urlencode-doesnt-like-unicode-values-how-about-this-workaround

comment:8 by Tim Graham, 9 years ago

The discussion on django-developers hasn't yielded a consensus on what the solution should look like.

I closed #26276 as a duplicate -- it suggests adding query and fragment parameters to reverse().

comment:9 by Sina, 7 years ago

Any update on this guys? this is now more than 2 years!!!
Why a MUST have simple feature like this should take two years to implement?

comment:10 by Aymeric Augustin, 7 years ago

The reason is explained in the comment just above yours.

Please consider that you're expressing your frustration in a way that's unlikely to motivate volunteers to work for free for you.

comment:11 by Ning, 7 years ago

Cc: Ning added

comment:12 by Charalampos Tsimpouris, 6 years ago

It feels more like this is missing from core rather than an enhancement. A URL can be with a query string or without a query string, the same goes also for fragment and in any case all URLs are assumed to be valid. Having this in mind, it makes sense that url tag should handle all the above cases by default. That way, it would provide a robust and unified solution for URL creation, maybe with auto escape features. Now, by trying to write another tag and/or searching for a solution around the internet feels like django can't handle creating valid URLs? Based on the idea of Thomas Güttler, I was thinking parameters like get__{name}= would evaluate for the query string, fragmet= to the fragment URL, and get__dict= would accept a whole dict at once. That way, it is backwards compatible while also wrapping a whole new world.

Last edited 6 years ago by Charalampos Tsimpouris (previous) (diff)

comment:13 by Herbert Fortes, 6 years ago

Cc: Herbert Fortes added

comment:14 by Will Gordon, 6 years ago

Cc: Will Gordon added

comment:15 by Daniel Rios, 5 years ago

Owner: changed from nobody to Daniel Rios
Status: newassigned

comment:16 by thenewguy, 5 years ago

Cc: thenewguy added

Something prettier than {% url 'admin:login' %}?next={{ request.path|urlencode }} would be awesome and make templates more readable

comment:17 by Carsten Fuchs, 3 years ago

Cc: Carsten Fuchs added

comment:18 by Daniel Rios, 17 months ago

Hi- I am at the sprints of DjangoConEU 2023 and have rediscovered this ticket I assigned to myself long ago. I am restarting working on it!

comment:19 by Tom Carrick, 12 months ago

Cc: Tom Carrick added

comment:20 by Sage Abdullah, 12 months ago

Cc: Sage Abdullah added

comment:21 by Daniel Rios, 4 days ago

Owner: Daniel Rios removed
Status: assignednew
Note: See TracTickets for help on using tickets.
Back to Top