You don't specify whether you're using a Django form to upload the image, I assume so as it is in the form field that the validation is carried out.
What you could do is create a subclass of django.forms.fields.ImageField
to extend the functionality of to_python.
The file type check currently carried out in Django in to_python
looks like this
Image.open(file).verify()
Your subclass could look something like.
class DmitryImageField(ImageField):
def to_python(self, data):
f = super(DmitryImageField, self).to_python(data)
if f is None:
return None
try:
from PIL import Image
except ImportError:
import Image
# We need to get a file object for PIL. We might have a path or we might
# have to read the data into memory.
if hasattr(data, 'temporary_file_path'):
file = data.temporary_file_path()
else:
if hasattr(data, 'read'):
file = BytesIO(data.read())
else:
file = BytesIO(data['content'])
try:
im = Image.open(file)
if im.format not in ('BMP', 'PNG', 'JPEG'):
raise ValidationError("Unsupport image type. Please upload bmp, png or jpeg")
except ImportError:
# Under PyPy, it is possible to import PIL. However, the underlying
# _imaging C module isn't available, so an ImportError will be
# raised. Catch and re-raise.
raise
except Exception: # Python Imaging Library doesn't recognize it as an image
raise ValidationError(self.error_messages['invalid_image'])
if hasattr(f, 'seek') and callable(f.seek):
f.seek(0)
return f
You may notice this is most of the code from ImageField.to_python
and might prefer to just create a sub-class of FileField to use instead of ImageField
rather than subclassing ImageField
and duplicating much of its functionality. In this case make sure to add im.verify()
before the format check.
EDIT: I should point out that I've not tested this subclass.