我正在尝试单元测试我的文件上传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
我如何转换枕头图像,使其可序列化?
我不建议在这种情况下以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')
顺便说一下,根据您的使用情况,接受图像数据作为base 64编码字符串可能更方便。
您将文件转换为字节,这是不可JSON序列化的。
不知道您的API期望接收什么,我将不得不猜测您必须将file
编码为字符串:"image": file.decode('utf-8')
。
虽然单元测试的一般问题有许多解决方案,但图像上传到REST API