gpt4 book ai didi

python - Django:奇怪的 mark_safe 行为?

转载 作者:太空宇宙 更新时间:2023-11-03 13:24:31 24 4
gpt4 key购买 nike

我写了这个小函数来写出 HTML 标签:

def html_tag(tag, content=None, close=True, attrs={}):
lst = ['<',tag]
for key, val in attrs.iteritems():
lst.append(' %s="%s"' % (key, escape_html(val)))
if close:
if content is None: lst.append(' />')
else: lst.extend(['>', content, '</', tag, '>'])
else:
lst.append('>')
return mark_safe(''.join(lst))

效果很好,但后来我在 efficient string concatenation 上阅读了这篇文章(我知道这并不重要,但我想要一致性)并决定更新我的脚本:

def html_tag(tag, body=None, close=True, attrs={}):
s = StringIO()
s.write('<%s'%tag)
for key, val in attrs.iteritems():
s.write(' %s="%s"' % (key, escape_html(val)))
if close:
if body is None: s.write(' />')
else: s.write('>%s</%s>' % (body, tag))
else:
s.write('>')
return mark_safe(s.getvalue())

但现在当我尝试从我的模板中呈现时,我的 HTML 被转义。其他一切都完全一样。如果我用 return mark_safe(unicode(s.getvalue())) 替换最后一行,它会正常工作。我检查了 s.getvalue() 的返回类型。它应该是一个 str,就像第一个函数一样,那为什么会失败呢??

SafeString(s.getvalue()) 也失败,但 SafeUnicode(s.getvalue()) 成功。


我还想指出,我在另一个函数中使用了 return mark_safe(s.getvalue())没有奇怪的行为。


“调用堆栈”如下所示:

class Input(Widget):
def render(self):
return html_tag('input', attrs={'type':self.itype, 'id':self.id,
'name':self.name, 'value':self.value, 'class':self.itype})
class Field:
def __unicode__(self):
return mark_safe(self.widget.render())

然后 {{myfield}} 在模板中。所以它确实得到了 mark_safed 两次,我认为这可能是问题所在,但我也尝试删除它......我真的不知道是什么原因造成的,但这并不难变通,所以我想我不会为此烦恼。

最佳答案

小部件的 render 方法由 BoundField.__unicode__ 函数调用,该函数返回 SafeString 而不是(unicode 的子类。 )

Django 中的许多地方(例如 django.template.VariableNode.render)实际上会在字段实例本身上调用 force_unicode。这将产生执行 unicode(instance.__unicode__()) 的效果,因此即使 instance.__unicode__() 返回一个 SafeString 对象,它将成为一个普通的 unicode 对象。

为了说明,请看下面的代码片段:

from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe

class Foo(object):
def __unicode__(self):
return mark_safe("foo")

foo = Foo()
print "foo =", type(foo)

ufoo = unicode(foo)
print "ufoo =", type(ufoo)

forced_foo = force_unicode(foo)
print "forced_foo =", type(forced_foo)


bar = mark_safe("bar")
print "bar =", type(bar)

forced_bar = force_unicode(bar)
print "forced_bar =", type(forced_bar)

输出:

foo = <class 'testt.Foo'>
ufoo = <type 'unicode'>
forced_foo = <type 'unicode'>
bar = <class 'django.utils.safestring.SafeString'>
forced_bar = <class 'django.utils.safestring.SafeUnicode'>

关于python - Django:奇怪的 mark_safe 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2597184/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com