我正在尝试对上传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
如何转换枕头图像以使其可序列化?
答案 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的一般问题有很多解决方案