2015-06-14 69 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。