1

I have registered a class like below to have an admin panel to upload images:

android_dashboard.register(Banner, BannerAdmin)

The banner model is as below:

class Banner(models.Model):    
    image = ImageField(
        _('Image'), upload_to=upload_path, blank=True, null=True,
        content_types=['image/jpg', 'image/jpeg', 'image/png'],
        max_size=1 * 1024 * 1024, extensions=['jpg', 'jpeg', 'png']
    )    
    type_of_banner = models.CharField(_('Type of Banner'), max_length=3, default='web')

    class Meta:
        verbose_name = _('Banner')
        verbose_name_plural = _('Banners')

    def __str__(self):
        return '%s' % str(self.id)

And the model admin is like below:

class BannerAdmin(admin.ModelAdmin):
    model = Banner
    fields = ('image', 'type_of_banner')
    list_display = ('image', 'type_of_banner')

For now when I login into admin section I can upload image directly to server. But I want to check ratio before uploading the image.

The question is how and when should I check the image width & height before uploading the image?

Alireza
  • 6,497
  • 13
  • 59
  • 132

2 Answers2

1

You can create a custom form and have a clean method to check the width and height of the image

class BannerAdmin(admin.ModelAdmin):
    form = BannerForm
    model = Banner
    fields = ('image', 'type_of_banner')
    list_display = ('image', 'type_of_banner')


class BannerForm(forms.ModelForm):
    def clean_image(self):
        image = self.cleaned_data['image']
        #image.height, image.width
        return image
1

If you want to validate dimensions before you upload it to your django backend I think you would have to use a custom widget with javascript.

Something like this could work:

class CustomImageInput(widgets.FileInput):

    def __init__(self, max_width, max_height, attrs=None):
        super(CustomImageInput, self).__init__(attrs)
        self.attrs.update({
            'data-max-width': max_width,
            'data-max-height': max_height,
            'class': 'custom-image-widget'
        })

    class Media:
        js = ('custom_image_widget.js',)

custom_image_widget.js would contain somethink like:

window.URL = window.URL || window.webkitURL;

$(document).ready(function() {
    $(".custom-image-widget").change(function(e) {
        var data = $(this).data(),
            maxWidth = data.maxWidth,
            maxHeight = data.maxHeight;

        if ((file = this.files[0])) {
            var img = new Image();
            img.src = window.URL.createObjectURL( file );

            img.onload = function() {
                var width = img.naturalWidth,
                    height = img.naturalHeight;

                window.URL.revokeObjectURL( img.src );

                if( width > maxWidth || height > maxHeight ) {
                    // Show error message
                    $(this).val("");
                }
            };
        }
    }
    $(".custom-image-widget").each(function() {
        var data = $(this).data(),
            maxWidth = data.maxWidth,
            maxHeight = data.maxHeight;

    });
});

And then you need to attach this widget to your admin model ImageField:

class BannerAdminForm(forms.ModelForm):
    class Meta:
        model = Banner
        widgets = {
          'image': CustomImageInput(max_height=400, max_width=300),
        }
        fields = '__all__'

class BannerAdmin(admin.ModelAdmin):
    form = BannerAdminForm

I based the javascript on this answer

bertucho
  • 656
  • 4
  • 7
  • +1 Thank you for your answer, I just wanted to check the dimension after upload and before saving the model. – Alireza Mar 30 '19 at 13:20