Forcing ImageField width/height in django
March 2nd, 2008
Ultimately I had to force the size of a uploaded image in the django admin area to a fixed dimension of 620x250px. Even if it could look a simple thing, in fact it isn’t.
The main issue is that even if an ImageField has a width_field/height_field option that refers to (presumably) integer fields that will be auto-filled with the image size, we can’t ran a validator across those fields (we can do so only in a form, but my problem was to validate the image in the admin area). So we have to manually load the image in memory and run a custom validator that uses PIL to get the needed information and validate the image.
Here’s the resulting code for the model:
class FImage(models.Model):
...
img = models.ImageField(upload_to='images', blank=False,
verbose_name=_("Image"),
validator_list=[custom_validators.ImageLarge(620, 250,
_("The image must be 620x250px large!")), ],
help_text=_("Image must be 620x250px large."))
...
And for the validator (that you should put in some separated file):
from django.utils.translation import gettext_lazy as _
from django.core import validators
import StringIO
from PIL import Image
class ImageLarge(object):
def __init__(self, width, height, error_message=_("The image isn't as large as expected!")):
self.w, self.h, self.error_message = width, height, error_message
def __call__(self, field_data, all_data):
im = Image.open(StringIO.StringIO(field_data['content']))
if im.size[0] != self.w or im.size[1] != self.h:
raise validators.ValidationError, self.error_message
The main issue with this solution is that we store the entire image content in memory for processing through PIL. Additionally I don’t know if it will still work when the #2070 ticket’s patch will be included in trunk (and I didn’t checked with the
actual existing patch).
If you want, you can read the full discussion on django-users.