2015-06-14 61 views
0

我有一个堆叠内联显示。 Inline类的模型有一个ManyToMany关系的子对象。我想显示图像,但我看不到如何阻止django逃离html。好像我需要一个类似于“display_as”的函数,但是如何让django收集所有可用图像并将其显示在“checkboxSelectMultiple”中。在django管理控制台中,如何阻止字段集字段转义HTML?

仅供参考:我想在给他们展示之后再为图片添加一些排序。

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) 
    ) 

现在我不知道如果我在执行中的“不正确”的方式,或者如果它是正常的需要编写自定义窗口小部件,并覆盖渲染功能的东西。

回答

1

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

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

您也可以使用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) 

你不需要申请越狱()到每个参数,如果您忘记了一个漏洞和XSS漏洞,就有风险。

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

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

这应该解决您的问题。

+0

我已更新我的代码以反映您的建议。我仍然无法让模板跳过转义。看起来有些东西正在改变字符串,导致它失去其“安全”状态。 –

+0

您应该在模板中开启'autoescape'。把这个模板标签块中需要转义的代码。这应该可以解决你的问题。更新了ans以包含此内容。 –

0

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