Skip to main content
 首页 » 编程设计

python之将类标记为 "safe"以在模板中呈现

2025年05月04日15飞鱼

我正在编写一个将由自定义模板过滤器返回的类。它有一个 __str__返回 HTML 的方法。我不希望该 HTML 被转义。

我试过只调用 mark_safe在我的字符串上,然后从 __str__ 返回它方法,但结果被转义了。我假设这是因为 Django 在将对象转换为字符串之前检查对象是否安全?

我能否以某种方式将类本身标记为安全的?

例如

class ParagraphTag(object): 
    def __init__(self, text): 
        self.text = text 
 
    def __str__(self): 
        return mark_safe('<p>{}</p>'.format(self.text + 'baz')) 
 
@register.filter(name='paragraph_tag') 
def paragraph_tag(text): 
    return ParagraphTag(text) 

在模板中呈现段落标记对象然后导致它被转义。

例如{{ paragraph_tag }} -> <p>foo</p>

如果我调用 mark_safe在 ParagraphTag 上从我的模板过滤器返回时对象本身,然后它变成了 SafeBytes不是我想要的对象。我想在我的模板中提供丰富的对象,并且只在呈现时将其转换为字符串。

请您参考如下方法:

Django 通常使用 unicode() 从 Python 对象中获取字符串。您必须实现 __unicode__ 以便它返回安全的 Unicode 字符串。否则,将返回的默认值将从 __str__ 中获取,但会因转换而变得不安全。

作为记录,这是我用来诊断它的代码:

from django.utils.html import mark_safe 
 
class ParagraphTag(object): 
 
    def __init__(self, text): 
        self.text = text 
 
    def __str__(self): 
        return mark_safe('<p>{}</p>'.format(self.text + 'baz')) 
 
print str(ParagraphTag("foo")).__class__ 
print str(ParagraphTag("foo")) 
print  
print unicode(ParagraphTag("foo")).__class__ 
print unicode(ParagraphTag("foo")) 
print mark_safe(unicode(ParagraphTag("foo"))).__class__ 

这将输出:

<class 'django.utils.safestring.SafeBytes'> 
<p>foobaz</p> 
 
<type 'unicode'> 
<p>foobaz</p> 
<class 'django.utils.safestring.SafeText'> 

下面是一个将生成安全 Unicode 的类的示例:

class ParagraphTagFixed(object): 
 
    def __init__(self, text): 
        self.text = text 
 
    def __str__(self): 
        return unicode(self).encode("utf-8") 
 
    def __unicode__(self): 
        return mark_safe(u'<p>{}</p>'.format(self.text + u'baz')) 
 
print unicode(ParagraphTagFixed("foo")).__class__ 
print unicode(ParagraphTagFixed("foo")) 
print str(ParagraphTagFixed("foo")).__class__ 
print str(ParagraphTagFixed("foo")) 

它将显示:

<class 'django.utils.safestring.SafeText'> 
<p>foobaz</p> 
<class 'django.utils.safestring.SafeBytes'> 
<p>foobaz</p>