【问题标题】:How to check image width & height in Django admin class?如何在 Django 管理类中检查图像宽度和高度?
【发布时间】:2019-08-21 04:28:32
【问题描述】:

我已经注册了一个类似下面的类来拥有一个管理面板来上传图片:

android_dashboard.register(Banner, BannerAdmin)

横幅模型如下:

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)

模型管理员如下:

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

现在,当我登录管理部分时,我可以将图像直接上传到服务器。但我想在上传图像之前检查比率。

问题是在上传图片之前,我应该如何以及何时检查图片的宽度和高度?

【问题讨论】:

    标签: python django django-models django-modeladmin


    【解决方案1】:

    您可以创建一个自定义表单,并有一个干净的方法来检查图像的宽度和高度

    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
    

    【讨论】:

    • 它给出了错误'InMemoryUploadedFile' object has no attribute 'height'
    【解决方案2】:

    如果您想在 将其上传到 django 后端之前验证尺寸,我认为您必须使用带有 javascript 的自定义小部件。

    这样的事情可能会起作用:

    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 会包含类似这样的想法:

    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;
    
        });
    });
    

    然后您需要将此小部件附加到您的管理模型 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
    

    我的 javascript 基于 this answer

    【讨论】:

    • +1 谢谢你的回答,我只是想在上传后保存模型之前检查一下尺寸。
    猜你喜欢
    • 2011-08-28
    • 2017-03-24
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-07
    相关资源
    最近更新 更多