I have URLs like http://example.com/depict?smiles=CO&width=200&height=200 (and with several other optional arguments)
我有像http://example.com/descript?微笑=CO&width=200&height=200(还有其他几个可选参数)
My urls.py contains:
我的url。py包含:
urlpatterns = patterns('',
(r'^$', 'cansmi.index'),
(r'^cansmi$', 'cansmi.cansmi'),
url(r'^depict$', cyclops.django.depict, name="cyclops-depict"),
I can go to that URL and get the 200x200 PNG that was constructed, so I know that part works.
我可以访问那个URL并获得构建的200x200 PNG,所以我知道这个部分是有效的。
In my template from the "cansmi.cansmi" response I want to construct a URL for the named template "cyclops-depict" given some query parameters. I thought I could do
在我的模板中来自“cansmi”。我想为给定一些查询参数的命名模板“cyclop - describe”构造一个URL。我以为我能做到
{% url cyclops-depict smiles=input_smiles width=200 height=200 %}
{% url cyclop - describe smiles=input_smiles width=200 height=200 %}
where "input_smiles" is an input to the template via a form submission. In this case it's the string "CO" and I thought it would create a URL like the one at top.
其中“input_smiles”是通过表单提交给模板的输入。在这种情况下,它是字符串“CO”,我认为它会创建一个URL,就像上面的那个。
This template fails with a TemplateSyntaxError:
这个模板在TemplateSyntaxError中失败:
Caught an exception while rendering: Reverse for 'cyclops-depict' with arguments '()' and keyword arguments '{'smiles': u'CO', 'height': 200, 'width': 200}' not found.
在呈现时捕获一个异常:反转“cyclps - describe”with arguments '()和关键字参数“{'微笑':u' co ', 'height: 200, 'width': 200}'未找到。
This is a rather common error message both here on * and elsewhere. In every case I found, people were using them with parameters in the URL path regexp, which is not the case I have where the parameters go into the query.
在*和其他地方,这是一个非常常见的错误消息。在我发现的每一种情况下,人们都在URL路径regexp中使用这些参数,这不是我在查询中使用参数的情况。
That means I'm doing it wrong. How do I do it right? That is, I want to construct the full URL, including path and query parameters, using something in the template.
这意味着我做错了。我怎么做对了?也就是说,我希望使用模板中的某些东西来构造完整的URL,包括路径和查询参数。
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.
5 个解决方案
#1
19
Your regular expresion has no place holders (that's why you are getting NoReverseMatch):
你的正则表达式的值没有地方持有人(这就是为什么你越来越NoReverseMatch):
url(r'^depict$', cyclops.django.depict, name="cyclops-depict"),
You could do it like this:
你可以这样做:
{% url cyclops-depict %}?smiles=CO&width=200&height=200
URLconf search does not include GET or POST parameters
URLconf搜索不包括GET或POST参数
Or if you wish to use {% url %} tag you should restructure your url pattern to something like
或者,如果您希望使用{% url %}标签,您应该将您的url模式重构为类似的东西。
r'^depict/(?P<width>\d+)/(?P<height>\d+)/(?P<smiles>\w+)$'
then you could do something like
然后你可以做一些类似的事情
{% url cyclops-depict 200 200 "CO" %}
Follow-up:
追问:
Simple example for 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 could use this tag in your templates like so:
你可以在你的模板中使用这个标签:
{% myurl width=200 height=200 name=SomeName %}
and hopefully it should output something like
希望它能输出
/depict?width=200&height=200&name=SomeName
#2
43
Building an url with query string by string concatenation as suggested by some answers is as bad idea as building SQL queries by string concatenation. It is complicated, unelegant and especially dangerous with a user provided (untrusted) input. Unfortunately Django does not offer an easy possibility to pass query parameters to the reverse function.
按照某些答案的建议,通过字符串连接使用查询字符串构建url与通过字符串连接构建SQL查询一样不是个好主意。对于提供(不可信的)输入的用户来说,这是复杂的、不优雅的,尤其危险的。不幸的是,Django并没有提供将查询参数传递给反向函数的简便方法。
Python standard urllib however provides the desired query string encoding functionality.
然而,Python标准urllib提供了所需的查询字符串编码功能。
In my application I've created a helper function:
在我的应用程序中,我创建了一个助手函数:
def url_with_querystring(path, **kwargs):
return path + '?' + urllib.urlencode(kwargs)
Then I call it in the view as follows:
然后我在视图中这样称呼它:
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
Please note the proper encoding of special characters like space and exclamation mark!
请注意空格、感叹号等特殊字符的正确编码!
#3
11
Neither of the original answers addresses the related issue resolving URLs in view code. For future searchers, if you are trying to do this, use kwargs, something like:
最初的答案都没有解决在视图代码中解决url的相关问题。对于未来的搜索者,如果你想这么做,可以使用kwargs,比如:
reverse('myviewname', kwargs={'pk': value})
反向(myviewname,kwargs = { }“pk”:价值)
#4
9
I recommend to use builtin django's QueryDict. It also handles lists properly. End automatically escapes some special characters (like =
, ?
, /
, '#'):
我建议使用builtin django的QueryDict。它还能正确地处理列表。End自动转义一些特殊字符(如=、?、/、'#'):
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 will need to create custom template tag
要在模板中使用它,您需要创建自定义模板标记
#5
5
The answer that used urllib is indeed good, however while it was trying to avoid strings concatenation, it used it in path + '?' + urllib.urlencode(kwargs)
. I believe this may create issues when the path
has already some query parmas.
使用urllib的答案确实不错,但是当它试图避免字符串连接时,它使用了path + '?' + urllib.urlencode(kwargs)。我认为这可能会在路径已经有一些查询参数时产生问题。
A modified function would look like:
修改后的函数如下:
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)
#1
19
Your regular expresion has no place holders (that's why you are getting NoReverseMatch):
你的正则表达式的值没有地方持有人(这就是为什么你越来越NoReverseMatch):
url(r'^depict$', cyclops.django.depict, name="cyclops-depict"),
You could do it like this:
你可以这样做:
{% url cyclops-depict %}?smiles=CO&width=200&height=200
URLconf search does not include GET or POST parameters
URLconf搜索不包括GET或POST参数
Or if you wish to use {% url %} tag you should restructure your url pattern to something like
或者,如果您希望使用{% url %}标签,您应该将您的url模式重构为类似的东西。
r'^depict/(?P<width>\d+)/(?P<height>\d+)/(?P<smiles>\w+)$'
then you could do something like
然后你可以做一些类似的事情
{% url cyclops-depict 200 200 "CO" %}
Follow-up:
追问:
Simple example for 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 could use this tag in your templates like so:
你可以在你的模板中使用这个标签:
{% myurl width=200 height=200 name=SomeName %}
and hopefully it should output something like
希望它能输出
/depict?width=200&height=200&name=SomeName
#2
43
Building an url with query string by string concatenation as suggested by some answers is as bad idea as building SQL queries by string concatenation. It is complicated, unelegant and especially dangerous with a user provided (untrusted) input. Unfortunately Django does not offer an easy possibility to pass query parameters to the reverse function.
按照某些答案的建议,通过字符串连接使用查询字符串构建url与通过字符串连接构建SQL查询一样不是个好主意。对于提供(不可信的)输入的用户来说,这是复杂的、不优雅的,尤其危险的。不幸的是,Django并没有提供将查询参数传递给反向函数的简便方法。
Python standard urllib however provides the desired query string encoding functionality.
然而,Python标准urllib提供了所需的查询字符串编码功能。
In my application I've created a helper function:
在我的应用程序中,我创建了一个助手函数:
def url_with_querystring(path, **kwargs):
return path + '?' + urllib.urlencode(kwargs)
Then I call it in the view as follows:
然后我在视图中这样称呼它:
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
Please note the proper encoding of special characters like space and exclamation mark!
请注意空格、感叹号等特殊字符的正确编码!
#3
11
Neither of the original answers addresses the related issue resolving URLs in view code. For future searchers, if you are trying to do this, use kwargs, something like:
最初的答案都没有解决在视图代码中解决url的相关问题。对于未来的搜索者,如果你想这么做,可以使用kwargs,比如:
reverse('myviewname', kwargs={'pk': value})
反向(myviewname,kwargs = { }“pk”:价值)
#4
9
I recommend to use builtin django's QueryDict. It also handles lists properly. End automatically escapes some special characters (like =
, ?
, /
, '#'):
我建议使用builtin django的QueryDict。它还能正确地处理列表。End自动转义一些特殊字符(如=、?、/、'#'):
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 will need to create custom template tag
要在模板中使用它,您需要创建自定义模板标记
#5
5
The answer that used urllib is indeed good, however while it was trying to avoid strings concatenation, it used it in path + '?' + urllib.urlencode(kwargs)
. I believe this may create issues when the path
has already some query parmas.
使用urllib的答案确实不错,但是当它试图避免字符串连接时,它使用了path + '?' + urllib.urlencode(kwargs)。我认为这可能会在路径已经有一些查询参数时产生问题。
A modified function would look like:
修改后的函数如下:
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)