加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – Django:奇怪的mark_safe行为?

发布时间:2020-12-20 11:13:25 所属栏目:Python 来源:网络整理
导读:我写了这个小函数来写出 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
我写了这个小函数来写出 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,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会被转义.其他一切都完全一样.如果我用返回mark_safe(unicode(s.getvalue())替换最后一行,它可以正常工作.我检查了s.getvalue()的返回类型.它应该是一个str,就像第一个函数一样,为什么会失败?

使用SafeString(s.getvalue())也会失败,但使用SafeUnicode(s.getvalue())会成功.

我还想指出我在不同的函数中使用了返回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(实例.__ unicode __())的效果,因此即使实例.__ 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'>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读