How to create Django reverse / url using args requests?

I have URLs like http://example.com/depict?smiles=CO&width=200&height=200 (and with a few other optional arguments)

My urls.py contains:

urlpatterns = patterns('', (r'^$', 'cansmi.index'), (r'^cansmi$', 'cansmi.cansmi'), url(r'^depict$', cyclops.django.depict, name="cyclops-depict"), 

I can go to this URL and get the created PNG 200x200, so I know this part works.

In my template from the answer "cansmi.cansmi" I want to create a URL for the named template "cyclops-pictict" taking into account some request parameters. I thought I could do

{% url cyclops-pictict smiles = input_smiles width = 200 height = 200%}

where "input_smiles" is the input to the template by submitting the form. In this case, this is the string "CO", and I thought I would create a URL similar to the one at the top.

This template does not work with TemplateSyntaxError:

Showing exceptions when rendering: Reverse for 'cyclops-pictict' with arguments' () 'and keyword arguments' {' smiles': u'CO ',' height ': 200,' width ': 200}' not found.

This is a fairly common error message both here and in StackOverflow and elsewhere. In each case, I found that people used them with parameters in the URL regular expression URL, which does not match me where the parameters are included in the request.

This means that I am doing it wrong. How do I do it right? That is, I want to build the full URL, including the path and request parameters, using something in the template.

For reference,

 % python manage.py shell Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> from django.core.urlresolvers import reverse >>> reverse("cyclops-depict", kwargs=dict()) '/depict' >>> reverse("cyclops-depict", kwargs=dict(smiles="CO")) Traceback (most recent call last): File "<console>", line 1, in <module> File "/Library/Python/2.6/site-packages/django/core/urlresolvers.py", line 356, in reverse *args, **kwargs))) File "/Library/Python/2.6/site-packages/django/core/urlresolvers.py", line 302, in reverse "arguments '%s' not found." % (lookup_view_s, args, kwargs)) NoReverseMatch: Reverse for 'cyclops-depict' with arguments '()' and keyword arguments '{'smiles': 'CO'}' not found. 
+29
url django query-string reverse
May 6 '10 at 3:31
source share
6 answers

There are no place owners in your regular expresion (why you get NoReverseMatch):

 url(r'^depict$', cyclops.django.depict, name="cyclops-depict"), 

You can do it as follows:

 {% url cyclops-depict %}?smiles=CO&width=200&height=200 

URLconf search does not include GET or POST parameters

Or, if you want to use the tag {% url%}, you must change the structure of your URL to something like

 r'^depict/(?P<width>\d+)/(?P<height>\d+)/(?P<smiles>\w+)$' 

then you can do something like

 {% url cyclops-depict 200 200 "CO" %} 



Subsequent:

A simple example for a custom tag:

 from django.core.urlresolvers import reverse from django import template register = template.Library() @register.tag(name="myurl") def myurl(parser, token): tokens = token.split_contents() return MyUrlNode(tokens[1:]) class MyUrlNode(template.Node): def __init__(self, tokens): self.tokens = tokens def render(self, context): url = reverse('cyclops-depict') qs = '&'.join([t for t in self.tokens]) return '?'.join((url,qs)) 

You can use this tag in your templates like this:

 {% myurl width=200 height=200 name=SomeName %} 

and hopefully he should output something like

 /depict?width=200&height=200&name=SomeName 
+20
May 6 '10 at 3:38 a.m.
source share

Creating a URL with a query string by concatenating strings, as suggested in some answers, is as bad a idea as creating SQL queries by concatenating strings. This is difficult, difficult, and especially dangerous when a user enters (unreliable) input. Unfortunately, Django does not provide an easy way to pass request parameters to the inverse function .

However, the Python urllib standard provides the desired query string encoding functionality.

In my application, I created a helper function:

 def url_with_querystring(path, **kwargs): return path + '?' + urllib.urlencode(kwargs) # for Python 3, use urllib.parse.urlencode instead 

Then I call it like this:

 quick_add_order_url = url_with_querystring(reverse(order_add), responsible=employee.id, scheduled_for=datetime.date.today(), subject='hello world!') # http://localhost/myapp/order/add/?responsible=5& # scheduled_for=2011-03-17&subject=hello+world%21 

Pay attention to the correct encoding of special characters, such as space and exclamation point!

+46
Mar 17 '11 at 16:05
source share

I recommend using the built-in django QueryDict . It also handles lists correctly. End automatically escapes some special characters (e.g. = , ? , / , '#'):

 from django.http import QueryDict from django.core.urlresolvers import reverse q = QueryDict('', mutable=True) q['some_key'] = 'some_value' q.setlist('some_list', [1,2,3]) '%s?%s' % (reverse('some_view_name'), q.urlencode()) # '/some_url/?some_list=1&some_list=2&some_list=3&some_key=some_value' q.appendlist('some_list', 4) q['value_with_special_chars'] = 'hello=w#rld?' '%s?%s' % (reverse('some_view_name'), q.urlencode()) # '/some_url/?value_with_special_chars=hello%3Dw%23rld%3F&some_list=1&some_list=2&some_list=3&some_list=4&some_key=some_value' 

To use this in templates, you need to create your own template tag.

+12
Dec 24 '14 at 19:30
source share

None of the original answers relate to resolving URL problems in view code. For future users, if you are trying to do this, use kwargs, for example:

 reverse('myviewname', kwargs={'pk': value}) 
+8
Jan 02 '13 at 10:18
source share

The answer urllib used is really good, however, although he tried to avoid string concatenation, he used it in path + '?' + urllib.urlencode(kwargs) path + '?' + urllib.urlencode(kwargs) . I believe that this can create problems when path already has some parmas requests.

The modified function will look like this:

 def url_with_querystring(url, **kwargs): url_parts = list(urlparse.urlparse(url)) query = dict(urlparse.parse_qsl(url_parts[4])) query.update(kwargs) url_parts[4] = urllib.urlencode(query) return urlparse.urlunparse(url_parts) 
+5
Nov 11 '15 at 8:27
source share

A working variation of the previous answers and my experience with this material.

 from django.urls import reverse from django.utils.http import urlencode def build_url(*args, **kwargs): params = kwargs.pop('params', {}) url = reverse(*args, **kwargs) if params: url += '?' + urlencode(params) return url 

How to use:

 >>> build_url('products-detail', kwargs={'pk': 1}, params={'category_id': 2}) '/api/v1/shop/products/1/?category_id=2' 
+1
Sep 15 '18 at 11:29
source share



All Articles