簡體   English   中英

如何安全地覆蓋django.contrib.admin.utils quote()方法?

[英]How can I safely override the django.contrib.admin.utils quote() method?

似乎django.contrib.admin.utils中的quote()unquote()方法無法有效處理主鍵中的下划線。 具體來說,我有一些類似於cus_C2xVQnht字符串型主鍵,當我使用django管理界面通過小鉛筆圖標對其進行編輯時,彈出窗口將顯示錯誤,例如Customer with ID "cusÂxVQnht" doesn't exist. Perhaps it was deleted? Customer with ID "cusÂxVQnht" doesn't exist. Perhaps it was deleted? (它是在C2轉換為碼點00C2, 叫做,這對其他有效碼點也是如此(00C7,00C6,001B等)

如果我手動轉到客戶模型並找到ID,則可以將其拉出並進行編輯,但是當主鍵中帶有下划線時,URL編碼似乎無法正常工作。

經過大量的挖掘之后,我設法找到了埋在django.contrib.admin.utils內部的這兩個函數:

def quote(s):
    """
    Ensure that primary key values do not confuse the admin URLs by escaping
    any '/', '_' and ':' and similarly problematic characters.
    Similar to urllib.parse.quote(), except that the quoting is slightly
    different so that it doesn't get automatically unquoted by the Web browser.
    """
    if not isinstance(s, str):
        return s
    res = list(s)
    for i in range(len(res)):
        c = res[i]
        if c in """:/_#?;@&=+$,"[]<>%\n\\""":
            res[i] = '_%02X' % ord(c)
    return ''.join(res)


def unquote(s):
    """Undo the effects of quote(). Based heavily on urllib.parse.unquote()."""
    mychr = chr
    myatoi = int
    list = s.split('_')
    res = [list[0]]
    myappend = res.append
    del list[0]
    for item in list:
        if item[1:2]:
            try:
                myappend(mychr(myatoi(item[:2], 16)) + item[2:])
            except ValueError:
                myappend('_' + item)
        else:
            myappend('_' + item)
    return "".join(res)

它們似乎在管理模板渲染過程中的某個地方被調用,但是我無法弄清楚位置/頻率/所有位置,因此我決定做一個快速的猴子補丁來確定是否值得追求作為解決方案:我將quote()unquote()所有下划線更改為單quote中的問題字符列表中的下划線,例如:

  • quote() '_%02X'變為'.%02X'
  • unquote() split('_')變成split('.')
  • unquote() myappend('_' + item)成為myappend('.' + item)

完成此操作后,管理員可以正常工作,並且似乎附加到相關字段上的編輯圖標的鏈接指向正確的模型實例,因此我可以通過單擊鉛筆圖標進行編輯,而不會出現上述錯誤消息。

說了這么多,我似乎找不到安全地重寫這兩種方法的方法。 我真的不希望更改主鍵來消除下划線,因為數據庫中有很多鏈接模型,並且看起來這將成為一個巨大的痛苦。 該修補程序似乎更容易且更可靠,並且鑒於它在Django的早期版本中可以正常工作,所以我認為實現它不是一個壞主意。

那么,如何覆蓋這些方法? 或者,作為一個相關問題,我可以在模型的__str__方法中做些什么來緩解此問題? 我會比開始編寫覆蓋Django admin內部構件的自定義類快得多。 如果沒有其他解決方案,我需要一些幫助來適當地重組數據庫以調整主鍵,但是我可以說這些鍵在我正在運行的運行Django 1.11.6的“舊”站點上可以正常使用和Python 2.7.9(與當前的Django 2.1.1和Python 3.6.5相比)

請讓我知道是否可以提供更多信息。 謝謝!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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