Django Rest Framework - 单元测试图像文件上传

时间:2016-11-16 20:22:14

标签: django rest django-rest-framework

我正在尝试对上传REST API的文件进行单元测试。我在网上找到了一些使用Pillow生成图像的代码,但它无法序列化。

这是我生成图片的代码:

image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
file = BytesIO(image.tobytes())
file.name = 'test.png'
file.seek(0)

然后我尝试上传这张图片:

return self.client.post("/api/images/", data=json.dumps({
     "image": file,
     "item": 1
}), content_type="application/json", format='multipart')

我收到以下错误:

<ContentFile: Raw content> is not JSON serializable

如何转换枕头图像以使其可序列化?

2 个答案:

答案 0 :(得分:5)

在这种情况下,我不建议您将数据作为JSON提交,因为这会使问题复杂化。只需使用您要提交的参数和文件发出POST请求即可。 Django REST框架可以很好地处理它,而无需将其序列化为JSON。

我写了一个测试,用于将文件上传到API端点,这看起来像这样:

def test_post_photo(self):
    """
    Test trying to add a photo
    """
    # Create an album
    album = AlbumFactory(owner=self.user)

    # Log user in
    self.client.login(username=self.user.username, password='password')

    # Create image
    image = Image.new('RGB', (100, 100))
    tmp_file = tempfile.NamedTemporaryFile(suffix='.jpg')
    image.save(tmp_file)

    # Send data
    with open(tmp_file.name, 'rb') as data:
        response = self.client.post(reverse('photo-list'), {'album': 'http://testserver/api/albums/' + album.pk, 'image': data}, format='multipart')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

在这种情况下,我使用tempfile模块存储使用Pillow生成的图像。示例中使用的with语法允许您相对容易地在请求正文中传递文件的内容。

基于此,这样的事情应该适用于您的用例:

image = Image.new('RGBA', size=(50, 50), color=(155, 0, 0))
file = tempfile.NamedTemporaryFile(suffix='.png')
image.save(file)

with open(file.name, 'rb') as data:
    return self.client.post("/api/images/", {"image": data, "item": 1}, format='multipart')

顺便提一下,根据您的使用情况,将图像数据接受为基本的64位编码字符串可能更方便。

答案 1 :(得分:0)

您将文件转换为字节,而不是JSON可序列化的。

在不知道您的API期望接收的内容的情况下,我必须猜测您必须将css/...编码为字符串:file

虽然您的单元测试图像上传到REST API的一般问题有很多解决方案