Django管理后台如何显示缩略图图片

54

我试图在Django管理后台中显示缩略图,但我只能看到图像路径,而不是渲染后的图像。我不知道我做错了什么。

服务器媒体URL:

from django.conf import settings
(r'^public/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),

函数模型:

def image_img(self):
        if self.image:
            return u'<img src="%s" />' % self.image.url_125x125
        else:
            return '(Sin imagen)'
        image_img.short_description = 'Thumb'
        image_img.allow_tags = True

admin.py:

class ImagesAdmin(admin.ModelAdmin):

    list_display= ('image_img','product',) 

结果如下:

<img src="http://127.0.0.1:8000/public/product_images/6a00d8341c630a53ef0120a556b3b4970c.125x125.jpg" />
6个回答

76

这是来自于photologue的源代码(请参见models.py,稍作修改以删除不相关的内容):

def admin_thumbnail(self):
    return u'<img src="%s" />' % (self.image.url)
admin_thumbnail.short_description = 'Thumbnail'
admin_thumbnail.allow_tags = True

list_display 部分看起来也完全相同,我知道它是有效的。唯一让我怀疑的是你的缩进 - 在你的 models.py 代码末尾以 image_img 开头的两行应该与 def image_img(self): 对齐,就像这样:

def image_img(self):
    if self.image:
        return u'<img src="%s" />' % self.image.url_125x125
    else:
        return '(Sin imagen)'
image_img.short_description = 'Thumb'
image_img.allow_tags = True

1
你把那个 image_img 函数放在哪里了?我已经写在 class ImagesAdmin(admin.ModelAdmin): 下面了,但是它报错说 Caught TypeError while rendering: image_img() takes exactly 1 argument (2 given) - brsbilgic
@brsbilgic - 除非您在self之后添加一个名为obj的第二个参数,表示您正在使用的模型,否则它需要放在您的模型下面。详情请参见https://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-methods。 - Dominic Rodger
如果我还想在模型的编辑页面上显示缩略图怎么办?只是为了参考,让用户知道当前上传的是哪张图片? - alfetopito
明白了 https://dev59.com/NGQo5IYBdhLWcg3wG8WE (如果还有其他人也在疑惑) - alfetopito

12

更新版本 v. 1.9

请注意,在 Django v.1.9 中

image_tag.allow_tags = True

被弃用,你应该使用format_html()、format_html_join()或mark_safe()代替

因此,你的model.py应该像这样:

...
from django.utils.html import mark_safe

def image_img(self):
    if self.image:
        return mark_safe('<img src="%s" />' % self.image.url_125x125)
    else:
        return '(Sin imagen)'
    image_img.short_description = 'Thumb'

并且在你的admin.py中添加:

list_display= ('image_img','product',)
readonly_fields = ('image_img',)

要将其添加到您的管理面板的“编辑模式”中,请在您的 admin.py 文件中添加:

fields = ( 'image_img', )

注意:image_img()方法应该接受一个instance参数:def image_img(self, instance):,并使用instance而不是self来获取URL。 - Phil Gyford
def image_img(self):,然后您可以使用self.field_name来获取字段,不需要实例参数(我的Django版本为v1.9)@ Phil Gyford - Cloud

7
在你的模型 (models.py) 中添加一个方法:
def image_tag(self):
    return u'<img src="%s" />' % <URL to the image>
image_tag.short_description = 'Image'
image_tag.allow_tags = True

在您的ModelAdmin(admin.py)中添加:

readonly_fields = ('image_tag',)

1
不要忘记也将 image_tag 添加到字段中: fields = ['image_tag', ...] - Hein van Dyke

6

继@dominic之后,我希望在多个模型中使用它,因此我创建了一个可以在每个模型中调用的函数,输入要显示的图像。

例如,在我的一个应用程序中:

from django.contrib import admin

from .models import Frontpage
from ..admin import image_file


class FrontpageAdmin(admin.ModelAdmin):
    list_display = ('image_thumb', ...)

    image_thumb = image_file('obj.image()') 

admin.site.register(Frontpage, FrontpageAdmin)

使用Frontpage的image函数返回一张图片。

在另一个应用中,我有:

from django.contrib import admin

from .models import Exhibition
from ..admin import image_file


class ExhibitionAdmin(admin.ModelAdmin):
    list_display = ('first_image_thumb', ...)

    first_image_thumb = image_file('obj.related_object.image',
                                   short_description='First Image')

admin.site.register(Exhibition, ExhibitionAdmin)

这使我可以指定图像对象和short_description,同时将样板文件保留在另一个文件中。函数如下:

from sorl.thumbnail import get_thumbnail
from django.conf import settings


def image_file(image, short_description='Image'):
    def image_thumb(self, obj):
        image = eval(image_thumb.image)
        if image:
            thumb = get_thumbnail(image.file, settings.ADMIN_THUMBS_SIZE)
            return u'<img width="{}" height={} src="{}" />'.format(thumb.width, thumb.height, thumb.url)
        else:
            return "No Image"

    image_thumb.__dict__.update({'short_description': short_description,
                                 'allow_tags': True,
                                 'image': image})
    return image_thumb

3

自从allow_tags已经被弃用,您应该使用format_html函数。示例代码如下:

models.py文件:

class TestAdminModel(models.Model):

    img = models.URLField()

admin.py 文件:

from django.utils.html import format_html

class TestAdmin(admin.ModelAdmin):
    list_display = ["id", "img", "thumbnail"]

    def thumbnail(self, obj):
        return format_html('<img src="{}" style="width: 130px; \
                           height: 100px"/>'.format(obj.img))

    thumbnail.short_description = 'thumbnail'

admin.site.register(models.TestAdminModel, TestAdmin)

结果看起来是这样的:enter image description here 您可以从Django文档中查看更多细节。

1
使用django-imagekit,您可以像这样添加任何图像:
from imagekit.admin import AdminThumbnail

@register(Fancy)
class FancyAdmin(ModelAdmin):
    list_display = ['name', 'image_display']
    image_display = AdminThumbnail(image_field='image')
    image_display.short_description = 'Image'

    # set this to also show the image in the change view
    readonly_fields = ['image_display']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接