#25582: Add a way to build URLs with query strings

484 views
Skip to first unread message

guettli

unread,
Oct 23, 2015, 3:41:42 AM10/23/15
to Django developers (Contributions to Django itself)
From  https://code.djangoproject.com/ticket/25582

 {{{

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.
}}}

{{{
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.
}}}

What do you think?



Tim Graham

unread,
Oct 23, 2015, 7:43:18 AM10/23/15
to Django developers (Contributions to Django itself)
Can you make an API proposal?

guettli

unread,
Oct 23, 2015, 7:59:25 AM10/23/15
to Django developers (Contributions to Django itself)
API proposal:

Add a new kwarg to reverse():

   reverse(..., get=None)


Example: reverse('my_view_name', kwargs={'pk': '1'}, get=dict(param='value')

result: /my-view/1?param=value

Dheerendra Rathor

unread,
Oct 23, 2015, 8:15:11 AM10/23/15
to Django developers (Contributions to Django itself)
How about a wrapper over reverse? 
Modifying reverse will lead to multiple changes in core urlresolver. 

A class based urlresolver can be implemented which will call reverse internally. 

Tom Evans

unread,
Oct 23, 2015, 10:05:01 AM10/23/15
to django-d...@googlegroups.com
On Fri, Oct 23, 2015 at 12:59 PM, guettli <guet...@thomas-guettler.de> wrote:
> API proposal:
>
> Add a new kwarg to reverse():
>
> reverse(..., get=None)
>
>
> Example: reverse('my_view_name', kwargs={'pk': '1'}, get=dict(param='value')

Would 'get' be a dict or a querydict? (URL parameters can be repeated,
dict keys cannot.)

Cheers

Tom

Collin Anderson

unread,
Oct 23, 2015, 11:18:38 AM10/23/15
to Django developers (Contributions to Django itself)
If it helps, I have a similar need in the template. My case requires adding, removing, or replacing one of the arguments on the fly:

In templates, I often need to change _one_ key of a GET request on the fly. My use case is a "filter by" sidebar on the same page as a "sort by" and "number per page". (Example: http://comcenter.com/category/BC020/ ).

I currently use a simple custom template tag:
@register.simple_tag
def make_query(params, key=None, value=None):
   
from django.utils.http import urlencode
   
if key:
       
params = params.copy()
       
if value:
           
params[key] = value
       
else:
           
params.pop(key, None)
   
return '?' + urlencode(params, True) if params else '.'

For previous/next pages, I simply use:
<a href="{% make_query request.GET "page" page.next_page_number %}">

For more complicated things, in the view I collect all of the valid params and pass them to the template. (I don't keep the "page" key in "params", because I want that to reset when filtering or sorting.)
<a href="{% make_query params "per_page" "24" %}">
<a href="{% make_query params filter.field_name option.new_param %}">

I can remove keys like so:
<a href="{% make_query params filter.field_name "" %}">Show All</a>

On Friday, October 23, 2015 at 3:41:42 AM UTC-4, guettli wrote:

Tim Graham

unread,
Oct 23, 2015, 3:39:33 PM10/23/15
to Django developers (Contributions to Django itself)
On the ticket, Luke pointed out these libraries:

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

He doesn't see a need to include a subset of the functionality provided by these libraries in Django itself.

I'm okay with that if it's the consensus but this brings up the question about to what extent the documentation should point to or endorse third-party packages.

guettli

unread,
Oct 26, 2015, 4:29:58 AM10/26/15
to Django developers (Contributions to Django itself)
Up to now you can change only one field in your make_query() method.
Flowing "think in sets" it would be nice to update N key-value pairs.

Merijn Bertels

unread,
Nov 9, 2015, 7:14:09 AM11/9/15
to Django developers (Contributions to Django itself)
I think would be a good thing if we create a function to support this. 
But I don't think it should be build in the reverse function. 

Like to point out that the Admin ChangeList has a function on the class who does something like this: 
each ListFilter use this function to generate a new url.

The downside of this is that ListFilters can not be re-used without a ChangeList. 



Op vrijdag 23 oktober 2015 09:41:42 UTC+2 schreef guettli:

Tino de Bruijn

unread,
Nov 14, 2015, 11:00:51 PM11/14/15
to django-d...@googlegroups.com
Would it be an idea to have QueryDict accept a dictionary to construct it? Then you could use it’s urlencode method to create the querysting. Seems like a logical place to implement this to me.

Tino

-- 
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/d13c725a-5dd4-4eda-9168-cc603fc7374e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rob Hudson

unread,
Nov 25, 2015, 12:08:44 AM11/25/15
to Django developers
At Mozilla we've used a jinja2 template filter called 'urlparams' for quite some time. You can see the code in jingo here:

In Python:
urlparams(reverse('translate', kwargs={'slug': document.slug}), to_locale=locale)

In Jinja2 templates (but the idea would be similar in Django):
<a href="{{ url('translate', slug=document.slug)|urlparams(to_locale=locale) }}

The nice thing about this is if a URL already have query string params, `urlparams` knows how to deal with this and it urlencodes all the variables provided.

Regardless of the API I would be pleased if something like this shipped standard with Django.

-Rob

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.

For more options, visit https://groups.google.com/d/optout.



--
-Rob
Reply all
Reply to author
Forward
0 new messages