我已经在 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 acorrupt 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/