首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ImageField不验证

ImageField不验证
EN

Stack Overflow用户
提问于 2019-08-07 08:07:51
回答 2查看 841关注 0票数 2

为什么Django的ImageField没有在这里抛出一个验证错误?

代码语言:javascript
复制
    # field in model
    image_mobile = ImageField(
        upload_to='static/images/',
        blank=True,
        null=True
    )

    # in test
    from django.core.files.uploadedfile import SimpleUploadedFile

    attachment = SimpleUploadedFile("file.mp4", b"file_content", content_type="text/plain")
    obj.image_mobile = attachment
    obj.save()
    self.assertEqual(obj.image_mobile, '')

产出如下:

代码语言:javascript
复制
AssertionError: <ImageFieldFile: static/images/file_7wanB5P.mp4> != ''

从文件中:

从FileField继承所有属性和方法,但也验证上载的对象是有效的图像。

EN

回答 2

Stack Overflow用户

发布于 2019-08-07 08:39:57

看来是PIL图书馆的事了。Django使用它获取图像维度,这似乎是ImageField的唯一验证。它获取文件的前1024字节并读取元数据,而且很可能mp4和jpeg有类似的数据。所以这不是最可靠的检查方法

代码语言:javascript
复制
 try:
    # Most of the time Pillow only needs a small chunk to parse the image
    # and get the dimensions, but with some TIFF files Pillow needs to
    # parse the whole file.
    chunk_size = 1024
    while 1:
        data = file.read(chunk_size)
        if not data:
            break
        try:
            p.feed(data)
        except zlib.error as e:
            # ignore zlib complaining on truncated stream, just feed more
            # data to parser (ticket #19457).
            if e.args[0].startswith("Error -5"):
                pass
            else:
                raise
        except struct.error:
            # Ignore PIL failing on a too short buffer when reads return
            # less bytes than expected. Skip and feed more data to the
            # parser (ticket #24544).
            pass
        except RuntimeError:
            # e.g. "RuntimeError: could not create decoder object" for
            # WebP files. A different chunk_size may work.
            pass
        if p.image:
            return p.image.size
        chunk_size *= 2
    return (None, None)
finally:
    if close:
        file.close()
    else:
        file.seek(file_pos)
票数 0
EN

Stack Overflow用户

发布于 2019-08-13 04:26:36

代码语言:javascript
复制
def to_python(self, data):
        """
        Check that the file-upload field data contains a valid image (GIF, JPG,
        PNG, etc. -- whatever Pillow supports).
        """
        f = super().to_python(data)
        if f is None:
            return None

        from PIL import Image

        # We need to get a file object for Pillow. We might have a path or we might
        # have to read the data into memory.
        if hasattr(data, 'temporary_file_path'):
            file = data.temporary_file_path()
        else:
            if hasattr(data, 'read'):
                file = BytesIO(data.read())
            else:
                file = BytesIO(data['content'])

        try:
            # load() could spot a truncated JPEG, but it loads the entire
            # image in memory, which is a DoS vector. See #3848 and #18520.
            image = Image.open(file)
            # verify() must be called immediately after the constructor.
            image.verify()

            # Annotating so subclasses can reuse it for their own validation
            f.image = image
            # Pillow doesn't detect the MIME type of all formats. In those
            # cases, content_type will be None.
            f.content_type = Image.MIME.get(image.format)
        except Exception as exc:
            # Pillow doesn't recognize it as an image.
            raise ValidationError(
                self.error_messages['invalid_image'],
                code='invalid_image',
            ) from exc
        if hasattr(f, 'seek') and callable(f.seek):
            f.seek(0)
        return f

这是运行的代码,如果您看到文档

https://pillow.readthedocs.io/en/5.1.x/reference/Image.html?highlight=verify#PIL.Image.Image.verify

Image.verify() 验证文件的内容。对于从文件中读取的数据,此方法尝试确定文件是否已损坏,而不实际解码图像数据。如果此方法发现任何问题,则会引发适当的异常。如果需要在使用此方法后加载图像,则必须重新打开图像文件。

因此,基本上它是试图确定该文件是否已损坏。而且可能是它正在验证您的mp4文件,这就是为什么没有例外。如果需要更严格的验证,则需要使用magic或其他库来确定文件类型。如下所示,线程相同

How does one use magic to verify file type in a Django form clean method?

Django: file field validation in model using python-magic

Django: Validate file type of uploaded file

https://timmyomahony.com/blog/upload-and-validate-image-from-url-in-django/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57389724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档