我有一个堆叠式内联显示器。 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
更新: 我发现我正在使用的小部件具有以下行的渲染功能:
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;方式或者是否需要编写自定义窗口小部件并覆盖渲染功能是正常的。
答案 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
内置模板标记。
此标记将on
或off
作为参数,并确定自动转义是否在块内生效。该块以endautoescape
结尾标记结束
当自动转义生效时,所有变量内容都会在将结果放入输出之前对其应用HTML转义(但在应用任何过滤器之后)。这相当于手动将转义过滤器应用于每个变量。
{% autoescape on %}
{{ image_object }}
{% endautoescape %}
这可以解决您的问题。
答案 1 :(得分:0)
我发现为我解决这个问题的方法是使用raw_id_field。