python - 为什么表单中的 ImageField 总是触发 "invalid_image"?

标签 python django django-models django-forms

我已经在 Django 1.8 中使用 Pillow 验证实现了 ImageField 来上传图像。由于某种原因,我无法提交表格。它总是在表单中引发此 ValidationError(但使用 FileField 这会起作用):

Upload a valid image. The file you uploaded was either not an image or a corrupted image.

所有这一切的奇怪之处在于 ImageField.check 方法似乎获得了正确的 MIME 类型! (见下文)

我尝试了什么

我尝试过 JPG、GIF 和 PNG 格式;没有一个工作。

所以我尝试在 django.forms.fields.ImageField 中打印一些变量,修改触发此错误的 try 语句,添加打印语句进行测试:

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.
    damnit = image.verify()
    print 'MY_LOG: verif=', damnit

    # 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)
    print 'MY_LOG: image_format=', image.format
    print 'MY_LOG: content_type=', f.content_type

然后我再次提交表单以在运行 python manage.py runserver 并获得这些行后触发错误:

MY_LOG: verif= None

MY_LOG: image_format= JPEG

MY_LOG: content_type= image/jpeg

图像被 Pillow 正确识别并且 try 语句一直执行到它的最后一行......但仍然触发了 except 语句?这毫无意义!

使用相同的策略,我尝试从 django.db.models.fields.files.ImageField 和它的每个父级获取一些有用的日志,直到 Field 打印错误列表...它们都是空的!

我的问题

还有什么我可以尝试找出触发 ValidationError 的原因吗?

一些代码

模型.py

class MyImageModel(models.Model):
    # Using FileField instead would mean succesfull upload
    the_image = models.ImageField(upload_to="public_uploads/", blank=True, null=True)

View .py

from django.views.generic.edit import CreateView
from django.forms.models import modelform_factory

class MyFormView(CreateView):
    model = MyImageModel
    form_class = modelform_factory(MyImageModel,
                 widgets={}, fields = ['the_image',])

编辑:

在尝试了@Alasdair 建议的策略后,我从e.message 获得了这份报告:

cannot identify image file <_io.BytesIO object at 0x7f9d52bbc770>

但是,即使不允许我提交表单,文件也已成功上传。看起来好像以某种方式未正确处理图像路径(或其他阻碍图像在这些行中加载的东西)。

我认为这些行可能有问题(来自 django.forms.fields.ImageField):

# 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'])

如果我探索这个类 BytesIO 有哪些属性,也许我可以提取一些关于错误的相关信息...

编辑2

data 属性到达空!确定原因并不容易...

最佳答案

来自 django 文档:

Using an ImageField requires that Pillow is installed with support for the image formats you use. If you encounter a corrupt image error when you upload an image, it usually means that Pillow doesn’t understand its format. To fix this, install the appropriate library and reinstall Pillow.

因此,首先,您应该安装 Pillow,而不是 PIL(pillow 是 PIL 的一个分支),其次,在安装时,确保安装了 Pillow 各种图像格式“理解”所需的所有库。

有关依赖项列表,您可以查看 Pillow 文档。

关于python - 为什么表单中的 ImageField 总是触发 "invalid_image"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34224182/

相关文章:

python - 如何在 Django 中为我的模型设置两个主键字段?

python - 我如何在Python中手动管理内存?

python - 替换数据框中表中的 NaN 值而不更改其他值

python - Django ORM,如何使用 values() 并仍然使用 choicefield?

带有内联模型的 Django 管理页面加载非常缓慢

python - 对象请求的 Django 动态过滤器数

python - 将外部 mysql 数据库连接到 django 应用程序并对其进行查询

python - 如何在Python中从Linux终端显示图形?

python - biopython - Entrez.esearch() 查询翻译与我的查询不符

django - Nginx 在 proxy_pass 之后使用 Upgrade header