似乎quote()
和unquote()
内的django.contrib.admin.utils
方法不能有效地处理主键中的下划线。具体来说,我有一些类似cus_C2xVQnht
的字符串类型主键,当我使用django管理界面通过小铅笔图标编辑它们时,弹出窗口将显示类似Customer with ID "cusÂxVQnht" doesn't exist. Perhaps it was deleted?
的错误(它正在将C2转换为代码点00C2,即。对于其他有效的代码点也是如此(00C7、00C6、001B等)
如果我手动转到customers模型并找到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)
它们似乎是在管理模板呈现过程中的某个地方调用的,但我不知道在何处/多久调用一次/所有位置,因此,我决定做一个快速的monkey补丁来决定它是否值得作为一个解决方案:我将quote()
和unquote()
中的所有下划线都改为点,除了quote
中问题字符列表中的一个…例如:
quote()
中的{'.%02X'
unquote()
中的{split('.')
unquote()
中的{myappend('.' + item)
在这样做之后,管理员工作正常,并且似乎附加到相关字段上的编辑图标的链接指向正确的模型实例,因此我可以通过单击铅笔图标来编辑它们,而不会得到上面提到的错误消息。你知道吗
尽管如此,我似乎找不到安全地覆盖这两种方法的方法。我真的不想更改主键来消除下划线,因为我的数据库中有很多链接模型,看起来这将是一个巨大的痛苦。这个修复看起来更简单、更可靠,而且考虑到它在Django以前的版本上正常工作,我不认为实现它是个坏主意。你知道吗
那么,我如何重写这些方法?或者,作为一个相关的问题,我是否可以在我的模型的__str__
方法中做些什么来缓解这个问题?我要比开始编写覆盖Django管理内部的自定义类快得多。如果没有其他解决方案,我将需要一些帮助来正确地重组数据库以调整主键,但我可以说,这些键在我正在工作的“旧”站点上运行得非常好,该站点运行Django 1.11.6和Python 2.7.9(与当前的Django 2.1.1和Python 3.6.5相比)
请让我知道如果我可以提供更多的信息。谢谢您!!你知道吗
这在django 2.2中是固定的。见https://github.com/django/django/commit/e4df8e6dc021fa472fa77f9b835db74810184748
相关问题 更多 >
编程相关推荐