在django admin中查看图片大小

wljmcqd8  于 2023-10-21  发布在  Go
关注(0)|答案(5)|浏览(157)

我看到很多使用Django应用程序的人在上传图像后会自动删除图像。这对某些情况来说是好的,但我不想这样做。相反,我只是想强制用户上传一个已经是正确大小的文件。
我想有一个ImageField,我迫使用户上传的图像是100x200。如果他们上传的图像不完全是这样的大小,我希望管理表格返回无效。我也希望能够为纵横比做同样的事情。我想迫使用户上传的图像是16:9,并拒绝任何上传不符合。
我已经知道如何获取图像的宽度和高度,但在图像上传和表单成功提交之前,我无法在服务器端执行此操作。如果可能的话,我怎么能更早地检查这个?

ou6hu8tu

ou6hu8tu1#

正确的做法是在表单验证期间执行此操作。
一个简单的例子(稍后将编辑/整合更多信息):

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)
ctrmrzij

ctrmrzij2#

在模型文件中使用此函数,

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')
tzxcd3kk

tzxcd3kk3#

我们也可以使用**class__call__()**方法来提供一些 * 参数
正如在编写验证器- Django脚本 * 中所建议的:
您也可以使用带有
__call__()方法的类来实现更复杂或可配置的验证器。例如,RegexValidator就使用了这种技术。如果在validatorsmodel field选项中使用了基于类的验证器,则需要通过添加 * deconstruct() * 和__eq__()**方法来确保迁移框架可以序列化。
下面是一个工作示例:

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
        )

而在模型中:

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")
    )
falq053o

falq053o4#

以上答案的更新和Models.py版本

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)
y53ybaqx

y53ybaqx5#

这可能是一个欺骗/非常类似于这个问题:
Using jQuery, Restricting File Size Before Uploading
我不认为有一种方法可以做到你想要的方式。Agos解决方案是要走的路...

**编辑:**链接SO问题中的一个答案谈到了使用Flash来完成。因此,虽然它可能会做一些其他的技术,我不认为你可以做它与直接JavaScript。

相关问题