如何在Django管理后台的“更改列表”页面中显示上传的图片?

38

我试图在Django管理页面的"更改列表"页面中显示上传的图片:

输入图像描述

以下是我的代码:

# "models.py"

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.DecimalField(decimal_places=2, max_digits=5)
    image = models.ImageField()
        
    def __str__(self):
        return self.name
# "admin.py"

from django.contrib import admin
from .models import Product

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ('name', 'price', 'image',)

那么,在 Django Admin 的"更改列表"页面中,我该如何显示已上传的图像?

9个回答

64
你可以创建一个模型实例方法并命名为其他名称,允许其输出包含HTML标签,并将此方法添加为列表字段。这里是一个示例: 首先添加一个新的方法,返回图像嵌入的HTML:
class Article(models.Model):
    ...
    def admin_image(self):
        return '<img src="%s"/>' % self.img
    admin_image.allow_tags = True

然后将这个方法添加到列表中:

class ArticleAdmin(admin.ModelAdmin):    
    ...
    list_display = ('url', 'title', 'admin_image')

有一个问题,请您看一下。在/admin/处出现了TypeError错误。'MediaDefiningClass'对象不可迭代。请求方法:GET 请求URL:http://127.0.0.1:8000/admin/ 异常类型:TypeError 异常值:'MediaDefiningClass'对象不可迭代。 - Oleg Tarasenko
1
实际上已经修复了之前的问题,现在出现了这个: “admin_img”不是....的可调用函数或属性。 - Oleg Tarasenko
提交了一个“编辑”以更正拼写错误。等待同行审查。 - jfunez
有没有办法给它一个自定义的标签/verbose_name?使用.short_description。 - radtek

28

更新2020

由于这个答案最近受到了很多关注,我决定进行小小的编辑。 根据django文档的建议,推荐使用函数format_html。 正如@chem1st建议的那样,如果您只需要它用于管理,一切都可以在admin.py中完成。

我的models.py

from django.db import models

class Product(models.Model):
    title = models.CharField(max_length=120)
    description = models.TextField()
    price = models.DecimalField(decimal_places = 2, max_digits = 20, default = 00.00)
    image = models.ImageField(upload_to=change_image_name, null=True, blank=True)

    def __str__(self):
        return self.title

我的 admin.py

from django.contrib import admin
from django.utils.html import format_html

from .models import Product

class ProductAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'price', 'image_tag')

    def image_tag(self,obj):
        return format_html('<img src="{0}" style="width: 45px; height:45px;" />'.format(obj.image.url))

admin.site.register(Product, ProductAdmin)

更新django 2.0.6

我在最新的django 2.0.6中解决了这个问题。我想在django-admin的列表视图中有一个图像缩略图。

下面的图片是我的默认管理列表视图。

这是我的默认管理员视图

这是我的models.py:

from django.db import models
from django.utils.safestring import mark_safe

# Create your models here.

class Product(models.Model):
    title = models.CharField(max_length=120)
    description = models.TextField()
    price = models.DecimalField(decimal_places = 2, max_digits = 20, default = 00.00)
    image = models.ImageField(upload_to=change_image_name, null=True, blank=True)

    def image_tag(self):
        if self.image:
            return mark_safe('<img src="%s" style="width: 45px; height:45px;" />' % self.image.url)
        else:
            return 'No Image Found'
    image_tag.short_description = 'Image'
    

    def __str__(self):
        return self.title

请注意,我必须在图像字符串上使用 mark_safe(),否则在 django-admin 中您将获得转义的 HTML 代码而不是缩略图。

最后,这是我的admin.py

from django.contrib import admin

from .models import Product
# Register your models here.
class ProductAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'price', 'image_tag')

admin.site.register(Product, ProductAdmin)

在这里,我们还需要注册 ProductAdmin 类,我不知道这一点,所以它没有起作用。

这是结果: enter image description here


4
谢谢,不过如果你只需要在管理后台使用 image_tag 方法的话,我建议把它移到 admin.py 文件里。请注意,我的翻译仅涉及翻译内容本身,不包括任何解释或其他信息。 - chem1st
@shaan gola - 不用谢,我已经对我的答案进行了小更新。祝你有美好的一天。 - TomRavn
抱歉会打扰,但我必须感谢您提供的这些细节;)在Django 3.2.x中运行正常。 - ali reza

14
def image_tag(self, obj):
    return u'<img src="%s" />' % obj.image

image_tag.short_description = 'Image'
image_tag.allow_tags = True

并在您的admin.py中添加:

   readonly_fields = ('image_tag',)

6

您也可以直接在管理后台添加图片。

class ProductAdmin(admin.ModelAdmin):
        
     def admin_image(self, obj):                       
        return '<img src="%s"/>' % obj.img
     admin_image.allow_tags = True

     list_display = ('name', 'price', 'image', 'admin_image')

更好的架构解决方案。 - SolessChong

1

1
你需要创建一个带有 image_tag的表格,并使用 image_tag() 函数将其分配给 list_display,如下所示:
# "admin.py"

from django.contrib import admin
from .models import Product
from django.utils.html import format_html

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):         # Here
    list_display = ('name', 'price', 'image', 'image_tag')

    def image_tag(self, obj): # Here
        return format_html(
            f'''<a href="{obj.image.url}" target="_blank">
                  <img 
                    src="{obj.image.url}" alt="{obj.image}" 
                    width="50" height="50"
                    style="object-fit: cover;"
                  />
                </a>''')

然后,您可以在Django管理页面的"更改列表"中显示上传的图像,如下所示:

enter image description here

您还可以查看我的回答,了解在Django管理界面的"修改"页面中如何显示已上传图像的方法。


0
models.py
from django.utils.html import format_html


class Test(models.Model):
    title                   = ...
    photo                   = ...
    
    def image(self):
        return format_html('<img src="%s"/>' % self.photo.url)
admin.py
@admin.register(models.Test)
class testAdmin(admin.ModelAdmin):
    list_display =    ('title','image')

0

0

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