2010-07-21 14 views
28

Próbuję wyświetlić miniatury obrazów w list_display Django admin i robię to tak:Prevent Django Admin ucieczce html

from django.utils.safestring import mark_safe 

class PhotoAdmin(admin.ModelAdmin): 
    fields = ('title', 'image',) 
    list_display = ('title', '_get_thumbnail',) 

    def _get_thumbnail(self, obj): 
     return mark_safe(u'<img src="%s" />' % obj.admin_thumbnail.url) 

Admin utrzymuje wyświetlanie miniatury jako zbiegłego html, choć oznaczone ciąg jako bezpieczny. Co ja robię źle?

Odpowiedz

67

Od Django 1.9 można użyć metody format_html(), format_html_join() lub allow_tags. Zobacz dokumentację list_display, aby uzyskać więcej informacji.

Kod w pytaniu za pomocą mark_safe zadziała. Jednak lepszą opcją dla takich metod może być format_html, co pozwoli uniknąć argumentów.

def _get_thumbnail(self, obj): 
    return format_html(u'<img src="{}" />', obj.admin_thumbnail.url) 

We wcześniejszych wersjach Django, używając mark_safe() nie będzie działać, a Django ucieknie wyjście. Rozwiązaniem było nadanie metodzie atrybutu allow_tags o wartości ustawionej na True.

class PhotoAdmin(admin.ModelAdmin): 
    fields = ('title', 'image',) 
    list_display = ('title', '_get_thumbnail',) 

    def _get_thumbnail(self, obj): 
     return u'<img src="%s" />' % obj.admin_thumbnail.url 
    _get_thumbnail.allow_tags = True 
+0

Dziękuję za wyjaśnienia, nie mogłem znaleźć tego w dokumentach. – Andy

+0

@Andy, jeśli to dla ciebie działa, kliknij znacznik wyboru pod partyturą, aby ta odpowiedź go zaakceptowała. –

+1

Nie jestem pewien, ale uważam, że właściwą składnią jest '{}', a nie '% s'. Tak więc byłoby to: 'format_html (u '', obj.admin_thumbnail.url). – Paolo

5

Wiem, że to dość późna odpowiedź, ale myślałem, że pełniejsza realizacja byłoby pomocne dla innych ...

Jeśli nie ma go już z django-filer, dostać easy_thumbnails pip install easy-thumbnails.

# -*- coding: utf-8 -*- 

from django.contrib import admin 

from easy_thumbnails.files import get_thumbnailer 

from models import Photo 


class PhotoAdmin(admin.ModelAdmin): 
    list_display = ('_thumbnail', 'title',) 
    list_display_links = ('_thumbnail', 'title',) # This makes the icon clickable too 
    readonly_fields = ('_thumbnail',) 
    fields = ('title', 'photo',) 

    def _thumbnail(self, obj): 
     if obj.photo: 
      thumbnailer = get_thumbnailer(obj.photo) 
      thumb = thumbnailer.get_thumbnail({ 
       'crop': True, 
       'size': (50, 50), 
       # Sharpen it up a little, since its so small... 
       'detail': True, 
       # Put other options here... 
      }) 
      # Note: we get the actual width/height rather than 
      # hard-coding 50, 50, just to be DRYer 
      return u'<img src="%s" alt="thumbnail: %s" width="%d" height="%d"/>' % (thumb.url, obj.photo.name, thumb.width, thumb.height) 
     else: 
      return "[No Image]" 

    # Optional, Provide a nicer label in the display 
    _thumbnail.short_description = 'Thumbnail' 

    # Required, leaves the markup un-escaped 
    _thumbnail.allow_tags = True 

admin.site.register(Photo, PhotoAdmin)