将BinaryField的文件上载小部件添加到Django Admin

将BinaryField的文件上载小部件添加到Django Admin,django,django-admin,Django,Django Admin,我们需要将一些较小的文件存储到数据库中(是的,我很清楚这些反驳,但是设置例如FileField在多个环境中工作对于几个文件来说似乎非常繁琐,在数据库中存储文件也可以解决备份要求) 然而,我惊讶地发现,即使BinaryField可以设置为可编辑,Django Admin也没有为它创建文件上传小部件 BinaryField唯一需要的功能是可以上载文件并替换现有文件。除此之外,Django管理员满足了我们的所有需求 我们如何修改Django Admin?您需要创建一个自定义的小部件,专门用于二进制字段

我们需要将一些较小的文件存储到数据库中(是的,我很清楚这些反驳,但是设置例如FileField在多个环境中工作对于几个文件来说似乎非常繁琐,在数据库中存储文件也可以解决备份要求)

然而,我惊讶地发现,即使BinaryField可以设置为可编辑,Django Admin也没有为它创建文件上传小部件

BinaryField唯一需要的功能是可以上载文件并替换现有文件。除此之外,Django管理员满足了我们的所有需求


我们如何修改Django Admin?

您需要创建一个自定义的
小部件
,专门用于
二进制字段
,它必须在将文件内容放入数据库之前读取文件内容

class BinaryFileInput(forms.ClearableFileInput):

    def is_initial(self, value):
        """
        Return whether value is considered to be initial value.
        """
        return bool(value)

    def format_value(self, value):
        """Format the size of the value in the db.

        We can't render it's name or url, but we'd like to give some information
        as to wether this file is not empty/corrupt.
        """
        if self.is_initial(value):
            return f'{len(value)} bytes'


    def value_from_datadict(self, data, files, name):
        """Return the file contents so they can be put in the db."""
        upload = super().value_from_datadict(data, files, name)
        if upload:
            return upload.read()
然后您需要以以下方式在admin中使用它:

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.BinaryField: {'widget': BinaryFileInput()},
    }

    fields = ('name', 'your_binary_file')
注:

  • BinaryField
    没有url或文件名,因此无法检查数据库中的内容
  • 上传文件后,您将能够看到数据库中存储的值的字节大小
  • 您可能希望扩展小部件以便能够下载文件 通过阅读它的内容

@Ania Warzecha,很抱歉,如何扩展下载