簡體   English   中英

模板url逆轉轉義surt參數

[英]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 %}的模板調用中對此沒有覆蓋。

請注意斜體文本詳細說明了更改。

這是iri_to_uri()

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM