[英]template url reversal escaping surt arguments
我遇到一个问题,其中模板网址反向转义了冒号和括号字符。 我希望这些字符在锚标记的href属性中保持不转义 。 在django 1.3中时,它曾经以这种方式运行,但是在升级到1.6时,我注意到这并没有达到我想要的状态。
我有的:
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属性中进行了转义。我不希望这样。
我想要的是:
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>
反向定位锚标记中的URL时,有人知道如何防止这些字符转义吗?
注意:以下答案是错误的。 urllib.quote(safe =':()')确实会使那些安全字符不转义。 django中正在发生其他事情,导致此问题,但我仍然不知道它在哪里。
在Django 1.6中,模板中的所有url反转都必须先通过iri_to_uri()
传递,然后再呈现为HTML。 按原样对url反向{% url %}
的模板调用中对此没有覆盖。
请注意此斜体文本详细说明了更改。
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="/#%[]=:;$&()+,!?*@'~")
乍看起来,这看起来像:
, (
和)
urllib.quote()
转义的十六进制编码,因为它们作为“安全”传递给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-2.3节的安全性”。 也许更精心命名的关键字参数是审慎的,但是话又说回来,关于urllib
我发现有些事情令人尴尬。 ಠ_ಠ
经过大量研究,并且由于我们不想修改Django核心方法,我们的团队决定在模板中进行一些复杂的url构造(非常友好的Django文档eschew )。 它不是完美的,但适用于我们的用例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.