【问题标题】:How to show BinaryField image preview in Django admin interface?如何在 Django 管理界面中显示 BinaryField 图像预览?
【发布时间】:2019-12-01 08:51:45
【问题描述】:

我有一个带有 Django 后端的 web 项目,我决定将图像存储为 BinaryField,这对我来说似乎更方便进行备份和恢复它们。

一开始我已经创建了模型:

class ThermalSource(ClusterUnit):
    ...
    scheme_image = models.BinaryField(verbose_name='Scheme', blank=True, null=True, editable=True)
    ...

然后创建序列化器以在视图集中使用(我知道它与管理界面无关,但也许会有用):

class Base64BinaryField(serializers.Field):

    def to_representation(self, value):
        from base64 import b64encode
        return b64encode(value)

    def to_internal_value(self, data):
        from base64 import b64decode
        return b64decode(data)


class ThermalSourceSerializer(APAMModelSerializer):
    ...
    scheme_image_base64 = Base64BinaryField(source='scheme_image')
    ...

现在我可以通过 Django REST Framework 正确获取和设置转换为 Base64 的图像。

ThermalSource 的管理类现在看起来如此:

class ThermalSourceForm(forms.ModelForm):

    scheme_image = forms.FileField(required=False)

    def save(self, commit=True):
        if self.cleaned_data.get('scheme_image') is not None \
                and hasattr(self.cleaned_data['scheme_image'], 'file'):
            data = self.cleaned_data['scheme_image'].file.read()
            self.instance.scheme_image = data
        return self.instance

    def save_m2m(self):
        # FIXME: this function is required by ModelAdmin, otherwise save process will fail
        pass

class ThermalSourceAdmin(admin.ModelAdmin):
    form = ThermalSourceForm
    readonly_fields = ('id', )
    list_display = ('id', ... 'scheme_image')

但是当我打开 Django 管理界面时,我只能下载文件到方案图像字段,没有配置预览。

谁能建议我如何为我的模型配置管理类,以便能够在 Django 管理界面中查看图像预览?

【问题讨论】:

    标签: python django


    【解决方案1】:

    拳头,将下面的代码添加到你的模型中。

    def scheme_image_tag(self):
        from base64 import b64encode
        return mark_safe('<img src = "data: image/png; base64, {}" width="200" height="100">'.format(
            b64encode(self.scheme_image).decode('utf8')
        ))
    
    scheme_image_tag.short_description = 'Image'
    scheme_image_tag.allow_tags = True
    

    然后,您可以在您的list_display(管理员)上呈现此字段。

    list_display = (...'scheme_image_tag')
    

    正如@DmitriyVinokurov 所说,您可以将此标签添加到readonly_fields

    readonly_fields = (..., 'scheme_image_tag')
    

    附:这个answer 解释了我为什么使用decode('utf8')

    【讨论】:

    • 酷,谢谢!一个评论和一个问题。评论 - 我将标签添加到 readonly_fields 而不是 list_display 因为我希望它显示在项目详细信息页面上,而不是在列表页面上。问题-也许您还可以帮助我找到如何从管理界面清除二进制字段以使此解决方案完整?
    • 嗨,@DmitriyVinokurov。我很高兴能帮助你。关于您的问题:clear binary field 是什么意思?。
    • 我的意思是将None 设置为scheme_image 实例的scheme_image 值。在管理界面中,我只看到上传文件的文件选择器,没有按钮,因此将其设置为 None
    • 嗨,@DmitriyVinokurov。默认情况下没有清除按钮,但您可以实现 admin action 或使用此 package 将操作添加到详细视图。
    • 嗨!谢谢您的回复。试过django-admin-object-actions 包。遵循github.com/ninemoreminutes/django-admin-object-actions/blob/… 中的fail 操作示例,经过几次尝试,我创建了自己的解决方案。一个问题 - 我创建了def clear_scheme_image(obj: ThermalSource, form) 函数,对其进行了测试并得到了clear_scheme_image takes 2 positional arguments but 3 were given 错误。在函数 args 列表定义的末尾添加了假 some_parameter - 另一个错误,开始 - 好的。我真的很好奇这个参数到底是什么:)
    猜你喜欢
    • 2011-01-27
    • 2012-12-13
    • 1970-01-01
    • 2017-08-12
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    相关资源
    最近更新 更多