Allow SVG files to be uploaded to ImageField via Django admin

It turns out that SVGAndImageFormField has no dependencies on DRF's ImageField, it only adds to the validation done by django.forms.ImageField.

So to accept SVGs in the Django Admin I changed the model's ImageField to a FileField and specified an override as follows:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        exclude = []
        field_classes = {
            'image_field': SVGAndImageFormField,
        }

class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm

admin.site.register(MyModel, MyModelAdmin)

It now accepts all previous image formats along with SVG.

EDIT: Just found out that this works even if you don't switch from models.ImageField to models.FileField. The height and width attributes of models.ImageField will still work for raster image types, and will be set to None for SVG.


I have never used SVGAndImageFormField so I cannot really comment on that. Personally I would have opted for a simple application of FileField, but that clearly depends on the project requirements. I will expand on that below:

As mentioned in the comment, the basic difference between an ImageField and a FileField is that the first checks if a file is an image using Pillow:

Inherits all attributes and methods from FileField, but also validates that the uploaded object is a valid image.

Reference: Django docs, Django source code

It also offers a couple of attributes possibly irrelevant to the SVG case (height, width).

Therefore, the model field could be:

    svg = models.FileField(upload_to=..., validators=[validate_svg])

You can use a function like is_svg as provided in the relevant question:

How can I say a file is SVG without using a magic number?

Then a function to validate SVG:

def validate_svg(file, valid):
    if not is_svg(file):
        raise ValidationError("File not svg")