tputkonen
tputkonen

Reputation: 5729

Adding file upload widget for BinaryField to Django Admin

We need to store a few smallish files to the database (yes, I'm well aware of the counterarguments, but setting up e.g. FileField to work in several environments seems very tedious for a couple of files, and having files on the database will also solve backup requirements).

However, I was surprised to find out that even though BinaryField can be set editable, Django Admin does not create a file upload widget for it.

The only functionality we need for the BinaryField is the possibility to upload a file and replace the existing file. Other than that, the Django Admin fulfills all our requirements.

How can we do this modification to Django Admin?

Upvotes: 2

Views: 1213

Answers (1)

Ania Warzecha
Ania Warzecha

Reputation: 1796

You will want to create a custom Widget specifically for BinaryField which has to read the file contents before putting them into the database.

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()

And then you need to use it in admin in the following way:

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

    fields = ('name', 'your_binary_file')

Note:

  • BinaryField doesn't have a url or a file name so you will not be able to check what's in the db
  • After uploading the file you will be able to see just the byte size of the value stored in the db
  • You might want to extend the widget to be able to download the file by reading it's contents

Upvotes: 1

Related Questions