在django管理控制台中,如何阻止字段集字段转义html?

时间:2015-06-14 05:47:06

标签: django django-admin

我有一个堆叠式内联显示器。 Inline类的模型具有ManyToMany关系中的子项。我想显示图像,但我看不到如何阻止django逃避html。看起来我需要一个类似" display_as"的函数,但是如何让django收集所有可用的图像并在" checkboxSelectMultiple"中显示它们。

仅供参考:我想在显示它们之后为图像添加一些排序。

Models.py

class BlogWidgetCarousel(models.Model):
    entry = models.TextField()
    blog = models.ForeignKey(Blog, blank=True, null=True)
    position = models.PositiveSmallIntegerField("Position")
    images = models.ManyToManyField("Image")

    class Meta:
        ordering = ('position', )

    def __str__(self):
        return str(self.position)

    def save(self, *args, **kwargs):
        self.entry = "<b><i>TODO: create image slider</i></b>"
        super(BlogWidgetCarousel, self).save(*args, **kwargs)

    def display(self):
        return self.entry  

class Image(models.Model):
    title = models.CharField(max_length=60, blank=False, null=False)
    image = models.ImageField(upload_to="images/")

    def thumb(self):
        return '<a href="{0}"><img src="{0}"></a>'.\
                    format(MEDIA_URL + str(self.image))

    def __str__(self):
        #return self.title
        #return '<img src="{0}">'.format(MEDIA_URL + str(self.image))
        return mark_safe("<b>BOLD</b>") #Added just to test escaping... bold tags still appear on page.
    __str__.allow_tags = True #does not appear to work

admin.py

class BlogWidgetCarouselInline(admin.StackedInline):
    formfield_overrides = {
        models.ManyToManyField: {'widget': CheckboxSelectMultiple},
    }
    model = BlogWidgetCarousel
    extra = 0
    #django knows images is ManyToMany
    fieldsets = (
        ("Create Carousel:", {
            'fields': (("position"), 'images',)
        }),
        ("Result:", {
            'fields': ('thumb', 'display_as',)
        }),
    )
    readonly_fields = ('display_as', 'thumb',)

    def display_as(self, instance):
        return instance.display()
    display_as.allow_tags = True

    def thumb(self, instance):
        x = ""
        for i in instance.images.all():
            x += i.thumb()
        return x 
    thumb.allow_tags = True

enter image description here

更新: 我发现我正在使用的小部件具有以下行的渲染功能:

return format_html( '<label{}>{} {}</label>', 
label_for, self.tag(attrs), self.choice_label)

这意味着模板使用的值已经转义。如此改变可以解决问题:

return format_html(
        '<label{}>{} {}</label>', label_for, self.tag(attrs), mark_safe(self.choice_label)
    )

现在我不确定我是否正在实施&#34;错误的&#34;方式或者是否需要编写自定义窗口小部件并覆盖渲染功能是正常的。

2 个答案:

答案 0 :(得分:1)

您可以使用format_html()django.utils.html模块提供了一些用于转义HTML的低级实用程序。

此函数优先于直接使用%str.format的字符串插值,因为它将转义应用于所有参数 - 就像模板系统默认应用转义一样。

您可以使用mark_safe()来转义HTML,如下所示:

mark_safe(u"%s <b>%s</b> %s" % (some_html,
                                escape(some_text),
                                escape(some_other_text),
                                ))

但是使用以下代码,

format_html(u"{0} <b>{1}</b> {2}", mark_safe(some_html), some_text, some_other_text)

您不需要对每个参数应用escape(),如果您忘记了漏洞,则可能会有漏洞和XSS漏洞。

您可以在模板中使用autoescape内置模板标记。 此标记将onoff作为参数,并确定自动转义是否在块内生效。该块以endautoescape结尾标记结束 当自动转义生效时,所有变量内容都会在将结果放入输出之前对其应用HTML转义(但在应用任何过滤器之后)。这相当于手动将转义过滤器应用于每个变量。

{% autoescape on %}
    {{ image_object }}
{% endautoescape %}

这可以解决您的问题。

答案 1 :(得分:0)

我发现为我解决这个问题的方法是使用raw_id_field。