Django framework makes storing image files against your database models easy via the ImageField field type. It does not however provide a way for you to validate the dimensions of this uploaded image.
This is of course important to do, otherwise your application will be hosting oversized images which could cause performance issues for end users.
In order to validate image dimensions at the model level we need to create a custom validator.
Here's the code for our validator:
from django.core.exceptions import ValidationError
def validate_minimum_size(width=None, height=None):
def validator(image):
error = False
if width is not None and image.width < width:
error = True
if height is not None and image.height < height:
error = True
if error:
raise ValidationError(
[f'Size should be at least {width} x {height} pixels.']
)
return validator
And here's how we can use that in our `models.py` module:
from django.db import models
class ExampleModel(models.Model):
avatar_image = models.ImageField(
null=True,
blank=True,
validators=[validate_minimum_size(width=98, height=98)],
)
When our model instance is saved this validator will be invoked and if the image is outside of our desired dimensions then an exception will be raised.
By using Django's built-in `ValidationError` errors will propagate all the way to the frontend of the application (if you're using Django forms linked to your templates).
If you're adding this to your project you may also want the tests ☑️
from unittest.mock import Mock
from myapp import validators
class TestValidateMinimumSize:
def test_does_not_raise_when_image_meets_requirements(self):
mock_image = Mock(width=10, height=10)
validator = validators.validate_minimum_size(width=10, height=10)
validator(image=mock_image)
def test_raises_if_image_is_too_small(self):
mock_image = Mock(width=9, height=9)
validator = validators.validate_minimum_size(width=10, height=10)
with pytest.raises(ValidationError):
validator(image=mock_image)