问题描述
我遇到一个问题,即模板网址反转正在转义冒号和括号角色。我希望这些字符在锚标签的href属性中 保持未转义 。我曾经在django 1.3中表现得很好,但是升级到1.6,我注意到这不符合我的要求。
I'm having an issue where the template url reversal is escaping colon and parenthetical characters. I want these characters to remain unescaped in the anchor tag's href attribute. It used to behave this way when I was in django 1.3, but upgrading to 1.6, I notice that this does not behave as I want.
我有什么: p>
What I have:
surt = 'http://(gov/'
browse_domain = 'gov'
... in template ...
<a href="{% url 'nomination.views.url_surt' project.project_slug surt %}">{{ browse_domain }}</a>
这将产生:
<a href="/nomination/eth2008/surt/http%3A//%28gov/">gov</a>
如您所见,冒号:
和左括号(
)正在转义字符url href属性我不想要。
As you can see, the colon :
and left parenthetical (
characters are being escaped in the url href attribute. I don't want that.
我想要什么:
surt = 'http://(gov/'
browse_domain = 'Gov'
... in template ...
<a href="{% url 'nomination.views.url_surt' project.project_slug surt %}">{{ browse_domain }}</a>
这将产生:
<a href="/nomination/eth2008/surt/http://(gov/">gov</a>
当我在我的锚标签中翻转网址时,任何人都知道如何保护这些字符不被转义? / p>
Anyone know how to keep these characters from escaping when I'm reversing URLs in my anchor tag?
推荐答案
注意:以下答案是错误的。 urllib.quote(safe =':()')确实会保留这些安全字符不被转义。在django发生其他事情导致这个问题,我仍然不知道它在哪里。
NOTE: The below answer is wrong. urllib.quote(safe=':()') will indeed keep those safe characters unescaped. Something else is happening in django to cause this problem and I still don't know where it is.
在Django 1.6中,任何url反转在模板将首先通过 iri_to_uri()
,然后再呈现为HTML。
在模板调用中没有任何替代方法,url反向 {%url%}
In Django 1.6, any url reversal in the template will first pass through iri_to_uri()
before it is rendered to HTML.There is no override for this in the template call to url reverse {% url %}
as-is.
请注意
def iri_to_uri(iri):
"""
Convert an Internationalized Resource Identifier (IRI) portion to a URI
portion that is suitable for inclusion in a URL.
This is the algorithm from section 3.1 of RFC 3987. However, since we are
assuming input is either UTF-8 or unicode already, we can simplify things a
little from the full method.
Returns an ASCII string containing the encoded result.
"""
# The list of safe characters here is constructed from the "reserved" and
# "unreserved" characters specified in sections 2.2 and 2.3 of RFC 3986:
# reserved = gen-delims / sub-delims
# gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
# / "*" / "+" / "," / ";" / "="
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
# Of the unreserved characters, urllib.quote already considers all but
# the ~ safe.
# The % character is also added to the list of safe characters here, as the
# end of section 3.1 of RFC 3987 specifically mentions that % must not be
# converted.
if iri is None:
return iri
return urllib.quote(smart_str(iri), safe="/#%[]=:;$&()+,!?*@'~")
乍一看,这可能看起来像:
,(
和)
可以避免转义的十六进制编码,因为它们被传递为 :
At first glance, this might look like :
, (
, and )
are safe from escaped hex-encoding because they are passed as 'safe' to urllib.quote()
:
_safe_map = {}
for i, c in zip(xrange(256), str(bytearray(xrange(256)))):
_safe_map[c] = c if (i < 128 and c in always_safe) else '%{:02X}'.format(i)
_safe_quoters = {}
def quote(s, safe='/'):
# fastpath
if not s:
if s is None:
raise TypeError('None object cannot be quoted')
return s
cachekey = (safe, always_safe)
try:
(quoter, safe) = _safe_quoters[cachekey]
except KeyError:
safe_map = _safe_map.copy()
safe_map.update([(c, c) for c in safe])
quoter = safe_map.__getitem__
safe = always_safe + safe
_safe_quoters[cachekey] = (quoter, safe)
if not s.rstrip(safe):
return s
return ''.join(map(quoter, s))
如果您通过实际的 urllib.quote()
方法如上所示,安全实际上意味着这些字符 将被转义/引用 。最初,我认为安全是指安全的引用。这给我造成了很大的困惑。我猜他们的意思是安全为RFC-3986的2.2-and-2.3。也许一个更精心地命名的关键字参数是谨慎的,但是再一次,我发现一些关于 urllib
的东西我觉得很尴尬。 ಠ_ಠ
If you step through the actual urllib.quote()
method as shown above, 'safe' actually means that those characters will be escaped/quoted. Initially, I thought 'safe' meant 'safe-from-quoting'. It caused me a great deal of confusion. I guess they instead mean, 'safe' as 'safe-in-terms-of-sections-2.2-and-2.3-of-RFC-3986'. Perhaps a more elaborately named keyword argument would be prudent, but then again, there's a whole cornucopia of things I find awkward regarding urllib
. ಠ_ಠ
经过多次研究,由于我们不想修改Django核心方法,我们的团队决定在模板(非常好的Django文档)。这不完美,但它适用于我们的用例。
After much research, and due to the fact that we don't want to modify Django core methods, our team decided to do some hacky url-construction in the template (the very kind Django docs strongly eschew). It's not perfect, but it works for our use case.
这篇关于模板url反转逃避争论的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!