-
-
Save ObserverOfTime/1a035e3a65e08aa5146eb120396d18ee to your computer and use it in GitHub Desktop.
A form field to handle validation of image + svg.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from xml.etree import cElementTree as et | |
from django.core.exceptions import ValidationError | |
from django.forms import ImageField | |
class SVGImageField(ImageField): | |
"""A Django ImageField that accepts SVG images.""" | |
def to_python(self, data): | |
""" | |
Check that the file-upload field data contains a valid image | |
(GIF, JPG, PNG, etc. -- whatever Pillow supports) or a SVG image. | |
""" | |
try: | |
file = super(SVGImageField, self).to_python(data) | |
except ValidationError as err: | |
# add a workaround to handle svg images | |
if not self.is_svg(file): | |
raise ValidationError( | |
self.error_messages['invalid_image'], | |
code='invalid_image', | |
) from err | |
file = super(ImageField, self).to_python(data) | |
file.content_type = 'image/svg+xml' | |
return file | |
def run_validators(self, value: str): | |
if not self.is_svg(value): | |
return super(ImageField, self).run_validators(value) | |
return super(SVGImageField, self).run_validators(value) | |
@staticmethod | |
def is_svg(file): | |
"""Check if the provided file is a SVG image.""" | |
file = file.seek(0) if hasattr(file, 'seek') else open(file) | |
try: | |
tag = '{http://www.w3.org/2000/svg}svg' | |
iter = et.iterparse(file, ('start',)) | |
return next(iter)[1].tag == tag | |
except et.ParseError: | |
return False | |
finally: | |
file.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment