Django 1.7 ImageField表单验证

时间:2014-10-01 12:48:59

标签: django forms validation django-1.7 django-tests

我正在使用Django 1.7和Python 3.4编写单元测试。当file_data元素被注释掉时,下面的表格会有效。如果包含file_data,则无法验证,测试失败。

from django.core.files.uploadedfile import SimpleUploadedFile
...

data = {
    'phone_number': '123456',
    'job': Job.objects.latest('id').pk,
}
file_data = {
    'portrait': SimpleUploadedFile(
        content=b'',
        content_type='image/jpeg',
        name='test.jpg',
    )
}
form = PersonForm(data, file_data)
self.assertTrue(form.is_valid())

类似的代码适用于我网站其他地方的FileField上传测试。在shell中运行代码我在form.errors中得到以下内容:'Upload a valid image. The file you uploaded was either not an image or a corrupted image.'因此,我认为问题出在contentcontent_type字段中。我尝试使用this answer中的图像作为字符串无效。 [编辑:图像作为一个字符串的方法实际上是答案,但我必须严格执行它。接受的答案已经过验证有效。] 我在SimpleUloadedFile source code找不到任何线索。

这种形式在现实中运作良好,但我想确保它在未来维护的工作测试中得到满足。理想情况下,我希望避免必须存在实际的test.jpg文件,因为图像位于我的.gitignore文件中,而且我不想开始攻击当前非常流畅的自动部署。

我应该给SimpleUploadedFile什么输入才能正确验证?

1 个答案:

答案 0 :(得分:4)

在您的测试套装和工作代码之间运行Image lib有什么区别吗? Image lib处理文件如GIF能正常吗?您可能还需要检查PIL/pillow安装。

SimpleUploadedFile(name='foo.gif', 
                   content=b'GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00')

适合我。

表单内部依赖forms.ImageField来测试to_python()中的图片,方式如下:

import io
from django.utils.image import Image
Image.open(io.BytesIO(image_content)).verify()

verify()行的任何异常都会导致错误'Upload a valid image...'。您可以通过将图像字节分配给image_content来检查图像字节:

image_content = b'GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00'

对我有用。

此外,您可以在线生成图像字节:

import io    
from django.utils.image import Image
fp = io.BytesIO()
Image.new('P', (1,1)).save(fp, 'png')
fp.seek(0)
portrait = SimpleUploadedFile(name=''foo, content=fp.read())