Reputation: 5496
I need to use the same custom validation in several forms. In other frameworks I would create a new "Validator" class but I'm not sure what's best with Django/Python.
Below is what I did, is there a better way (solution below)?
In any form:
def clean_image(self):
image = self.cleaned_data.get("image")
return validate_image_with_dimensions(
image,
expected_width=965,
expected_height=142
)
In a validation module
def validate_image_with_dimensions(image, expected_width, expected_height):
from django.core.files.images import get_image_dimensions
# the validation code...
return image
Below is the solution:
In the form:
image = forms.ImageField(
max_length=250,
label=mark_safe('Image<br /><small>(must be 1100 x 316px)</small>'),
required=True,
validators=[
ImageDimensionsValidator(
expected_width=1100,
expected_height=316
)
]
)
In a validation module:
class ImageDimensionsValidator(object):
def __init__(self, expected_width, expected_height):
self.expected_width = expected_width
self.expected_height = expected_height
def __call__(self, image):
"""
Validates that the image entered have the good dimensions
"""
from django.core.files.images import get_image_dimensions
if not image:
pass
else:
width, height = get_image_dimensions(image)
if width != self.expected_width or height != self.expected_height:
raise ValidationError(
"The image dimensions are: " + str(width) + "x" + str(height) + ". "
"It's supposed to be " + str(self.expected_width) + "x" + str(self.expected_height)
)
Upvotes: 2
Views: 800
Reputation: 62918
Form and model fields accept a list of validators:
class YourForm(forms.Form):
...
image = forms.ImageField(validators=[validate_image_with_dimensions])
A validator is a callable object of any kind, feel free to write callable classes (django internal validators are class-based).
For inspiration, look at django.core.validators source.
Upvotes: 2