我已使用Django 1.8
中的枕头验证实施了ImageField上传图片。出于某种原因,我无法提交表格。它总是在表单中引发这个ValidationError(但是使用FileField会起作用):
上传有效图片。您上传的文件不是图像或损坏的图像。
所有这一切的奇怪之处在于ImageField.check方法似乎获得了正确的MIME类型! (见下文)
我尝试过JPG,GIF和PNG格式;没人工作。
所以我尝试在django.forms.fields.ImageField
中修改一些变量来修改触发此错误的try
语句,添加用于测试的print语句:
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 =无
MY_LOG:image_format = JPEG
MY_LOG:content_type = image / jpeg
Pillow正确识别图像,并且执行try语句直到它的最后一行......仍然触发except语句?它使nosense!
使用相同的策略,我试图从django.db.models.fields.files.ImageField
及其所有父母那里获取有用的日志,直到Field
打印错误列表...所有这些都是空的!
还有什么我可以尝试发现触发ValidationError的内容吗?
models.py
class MyImageModel(models.Model):
# Using FileField instead would mean succesfull upload
the_image = models.ImageField(upload_to="public_uploads/", blank=True, null=True)
views.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
获得了此报告:
无法识别图像文件< _io.BytesIO对象位于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
有哪些属性,也许我可以提取一些有关错误的相关信息......
data
属性空了!确定为什么不容易......
答案 0 :(得分:1)
来自django文档:
使用
ImageField
要求安装Pillow并支持您使用的图像格式。如果您在上传图片时遇到corrupt image
错误,通常意味着Pillow不了解其格式。要解决此问题,请安装相应的库并重新安装Pillow。
首先,你应该安装Pillow,而不是PIL(枕头是PIL的叉子),其次,在安装时,确保安装Pillow各种图像格式“理解”所需的所有库。
有关依赖项列表,您可以查看Pillow文档。
答案 1 :(得分:0)
经过深思熟虑,分析隐含的代码和大量的反复试验后,我尝试从我在问题中公开的while(whatever)
{
if(some_condition)
{
if(condition1)
do_something1();
else if(condition2)
do_something2();
else if(condition3)
do_something3();
else if(condition4)
do_something4(); /* more than two hundred more `else if` */
}
}
块中编辑此行(在try / except
中)这样:
django.forms.fields.ImageField
这解决了我的问题。现在一切正常,我可以提交表格。相应的# Before edition
image = Image.open(file)
# After my edition
image = Image.open(f)
我不确定我是否猜对了,但是:
我认为这很有效,因为这行命名正确的变量有错误。此外,使用
ValidationError
作为变量名称看起来像是一个错字,因为file
似乎是为现有的内置保留的。{/ p>
如果我的猜测是正确的,也许我应该向Django开发人员报告此问题