61π
The right place to do this is during form validation.
A quick example (will edit/integrate with more info later):
from django.core.files.images import get_image_dimensions
from django.contrib import admin
from django import forms
class myForm(forms.ModelForm):
class Meta:
model = myModel
def clean_picture(self):
picture = self.cleaned_data.get("picture")
if not picture:
raise forms.ValidationError("No image!")
else:
w, h = get_image_dimensions(picture)
if w != 100:
raise forms.ValidationError("The image is %i pixel wide. It's supposed to be 100px" % w)
if h != 200:
raise forms.ValidationError("The image is %i pixel high. It's supposed to be 200px" % h)
return picture
class MyAdmin(admin.ModelAdmin):
form = myForm
admin.site.register(Example, MyAdmin)
6π
use this function in your model file,
from django.core.exceptions import ValidationError
def validate_image(fieldfile_obj):
filesize = fieldfile_obj.file.size
megabyte_limit = 2.0
if filesize > megabyte_limit*1024*1024:
raise ValidationError("Max file size is %sMB" % str(megabyte_limit))
class Company(models.Model):
logo = models.ImageField("Logo", upload_to=upload_logo_to,validators=[validate_image], blank=True, null=True,help_text='Maximum file size allowed is 2Mb')
- [Django]-ValueError β Cannot assign: must be an instance
- [Django]-How to force a user logout in Django?
- [Django]-How to use Django 1.8.5 ORM without creating a django project?
3π
We can also use a class
with a __call__()
method to provide some parameters.
As suggested in Writing validators β Django Docs:
You can also use a class with a
__call__()
method for more complex or
configurable validators.RegexValidator
, for example, uses this
technique. If a class-based validator is used in thevalidators
model
field option, you should make sure it is serializable by the migration
framework by addingdeconstruct()
and__eq__()
methods.
Here is a working example:
from collections.abc import Mapping
from django.utils.translation import gettext_lazy as _
from django.utils.deconstruct import deconstructible
@deconstructible
class ImageValidator(object):
messages = {
"dimensions": _(
"Allowed dimensions are: %(width)s x %(height)s."
),
"size": _(
"File is larger than > %(size)sKiB."
)
}
def __init__(self, size=None, width=None, height=None, messages=None):
self.size = size
self.width = width
self.height = height
if messages is not None and isinstance(messages, Mapping):
self.messages = messages
def __call__(self, value):
# _get_image_dimensions is a method of ImageFile
# https://docs.djangoproject.com/en/1.11/_modules/django/core/files/images/
if self.size is not None and value.size > self.size:
raise ValidationError(
self.messages['size'],
code='invalid_size',
params={
'size': float(self.size) / 1024,
'value': value,
}
)
if (self.width is not None and self.height is not None and
(value.width != self.width or value.height != self.height)):
raise ValidationError(
self.messages['dimensions'],
code='invalid_dimensions',
params={
'width': self.width,
'height': self.height,
'value': value,
}
)
def __eq__(self, other):
return (
isinstance(other, self.__class__) and
self.size == other.size and
self.width == other.width and
self.height == other.height
)
And than in model:
class MyModel(models.Model):
...
banner = models.ImageField(
upload_to='uploads/', verbose_name=_("Banner"),
max_length=255, null=True, blank=True,
validators=[ImageValidator(size=256000, width=1140, height=425)],
help_text=_("Please use our recommended dimensions: 1140 x 425 PX, 250 KB MAX")
)
- [Django]-Accessing "Media" files in Django
- [Django]-Django.db.utils.OperationalError: fe_sendauth: no password supplied
- [Django]-Django bulk_create with ignore rows that cause IntegrityError?
0π
Update and Models.py version of the above answer
from django.core.exceptions import ValidationError
from django.core.files.images import get_image_dimensions
class Model(models.Model):
photo = models.ImageField()
def clean(self):
if not self.photo:
raise ValidationError("No image!")
else:
w, h = get_image_dimensions(self.photo)
if w != 200:
raise ValidationError("The image is %i pixel wide. It's supposed to be 200px" % w)
if h != 200:
raise ValidationError("The image is %i pixel high. It's supposed to be 200px" % h)
- [Django]-What is a Django "app" supposed to mean?
- [Django]-In Django 1.4, do Form.has_changed() and Form.changed_data, which are undocumented, work as expected?
- [Django]-Django admin make a field read-only when modifying obj but required when adding new obj
-1π
This may be a dupe of/very similar to this question:
Using jQuery, Restricting File Size Before Uploading
I donβt think there is a way to do it the way you want. Agos solution is the way to goβ¦
Edit: One of the answers in the linked SO question talks about using flash to do it. So while it may be possible to do with some other technology, I donβt think you can do it with straight javascript.
- [Django]-How to customize the auth.User Admin page in Django CRUD?
- [Django]-Validators = [MinValueValidator] does not work in Django
- [Django]-How to completely uninstall a Django app?