Django 1.7 Проверка формы ImageField

Я пишу модульные тесты, используя 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 тестов загрузки в другом месте моего сайта. Запустив код в оболочке, я получаю следующее в form.errors: 'Upload a valid image. The file you uploaded was either not an image or a corrupted image.' Поэтому я думаю, что проблема заключается либо в полях content, либо в полях content_type. Я пытался использовать изображение как строку, как в этом ответе, но безрезультатно. [Редактировать: подход «изображение как строка» на самом деле был ответом, но я, должно быть, плохо его реализовал. Принятый ответ проверен как работающий.] Я не смог найти никаких подсказок в Исходный код SimpleUloadedFile.

На самом деле форма работает нормально, но я хочу убедиться, что она покрыта рабочим тестом для будущего обслуживания. В идеале я бы хотел избежать наличия фактического файла test.jpg, потому что изображения находятся в моем файле .gitignore, и я не хочу начинать взламывать то, что в настоящее время является очень плавным автоматическим развертыванием.

Какой ввод я должен ввести SimpleUploadedFile, чтобы он правильно прошел проверку?


person cms_mgr    schedule 01.10.2014    source источник


Ответы (1)


Есть ли разница в запуске Image lib между вашим тестовым костюмом и вашим рабочим кодом? Может ли библиотека Image правильно обрабатывать такие файлы, как 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())
person okm    schedule 01.10.2014
comment
Как ни странно, первое решение сработало сразу, но я могу поклясться, что это была одна из тех вещей, которые я пробовал. Должно быть, у меня где-то изначально была опечатка. Спасибо. - person cms_mgr; 02.10.2014