将课程标记为"安全"用于在模板中渲染

时间:2016-05-17 10:02:48

标签: python django django-templates

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

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

我能以某种方式将班级本身标记为安全吗?

e.g。

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)

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

e.g。 {{ paragraph_tag }} - &gt; <p>foo</p>

如果我在mark_safe对象本身从我的模板过滤器返回时调用ParagraphTag,那么它会变成SafeBytes对象,这不是我想要的。我想在我的模板中使用富对象,并且只在渲染时将其转换为字符串。

2 个答案:

答案 0 :(得分:4)

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>

答案 1 :(得分:2)

我认为Get-Content 'PATH_TO_YOUR_TXT_FILE' | ForEach-Object { Test-Connection $_ } 应该返回一个字符串。你的没有,这就是导致你麻烦的原因。

Django宁愿将__str__用于转义字符串。实际上,它提供了一个__html__裁剪程序,可根据您对html_safe的定义创建此方法。

在Python 3上,您可以像这样定义您的类:

__str__

在Python 2上:

from django.utils.html import html_safe

@html_safe
class Test():
    def __str__(self):
        return '<p>Hey</p>'

(或者您可以定义from django.utils.html import html_safe from django.utils.encoding import python_2_unicode_compatible @html_safe @python_2_unicode_compatible class Test(): def __str__(self): return '<p>Hey</p>' 而不是__unicode__)。