Opened 3 years ago

Last modified 3 weeks ago

#25582 new New feature

Add a way to build URLs with query strings

Reported by: Thomas Güttler Owned by: nobody
Component: Core (URLs) Version: master
Severity: Normal Keywords:
Cc: Ning, Herbert Fortes 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 (13)

comment:1 Changed 3 years ago by Tim Graham

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 Changed 3 years ago by Dheerendra Rathor

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 Changed 3 years ago by Luke Plant

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 Changed 3 years ago by Thomas Güttler

@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 Changed 3 years ago by Thomas Güttler

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

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

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.

comment:7 in reply to:  4 Changed 3 years ago by Thomas Güttler

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 Changed 3 years ago by Tim Graham

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 Changed 10 months ago by Sina

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 Changed 10 months ago by Aymeric Augustin

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 Changed 9 months ago by Ning

Cc: Ning added

comment:12 Changed 4 weeks ago by Charalampos Tsimpouris

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 4 weeks ago by Charalampos Tsimpouris (previous) (diff)

comment:13 Changed 3 weeks ago by Herbert Fortes

Cc: Herbert Fortes added
Note: See TracTickets for help on using tickets.
Back to Top