Python 如何使用rest\u framework.test.APITestCase发送多个文件
我正在尝试将几个文件发送到我的后端:Python 如何使用rest\u framework.test.APITestCase发送多个文件,python,testing,django-rest-framework,Python,Testing,Django Rest Framework,我正在尝试将几个文件发送到我的后端: class AccountsImporterTestCase(APITestCase): def test(self): data = [open('accounts/importer/accounts.csv'), open('accounts/importer/apartments.csv')] response = self.client.post('/api/v1/accounts/import/', dat
class AccountsImporterTestCase(APITestCase):
def test(self):
data = [open('accounts/importer/accounts.csv'), open('accounts/importer/apartments.csv')]
response = self.client.post('/api/v1/accounts/import/', data, format='multipart')
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
但我有一个错误:
Error
Traceback (most recent call last):
File "/vagrant/conjuntos/accounts/tests/cases.py", line 128, in test
response = self.client.post('/api/v1/accounts/import/', data, format='multipart')
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/test.py", line 168, in post
path, data=data, format=format, content_type=content_type, **extra)
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/test.py", line 89, in post
data, content_type = self._encode_data(data, format, content_type)
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/test.py", line 64, in _encode_data
ret = renderer.render(data)
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/renderers.py", line 757, in render
return encode_multipart(self.BOUNDARY, data)
File "/vagrant/venv/lib/python3.4/site-packages/django/test/client.py", line 156, in encode_multipart
for (key, value) in data.items():
AttributeError: 'list' object has no attribute 'items'
我知道我没有正确准备数据,但有可能吗?如何准备?。谢谢
更新:尝试@Kevin Brown解决方案
def test(self):
data = QueryDict('', mutable=True)
data.setlist('files', [open('accounts/importer/accounts.csv'), open('accounts/importer/apartments.csv')])
response = self.client.post('/api/v1/accounts/import/', data, format='multipart')
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
获得以下信息:
Error
Traceback (most recent call last):
File "/vagrant/conjuntos/accounts/tests/cases.py", line 130, in test
response = self.client.post('/api/v1/accounts/import/', data, format='multipart')
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/test.py", line 168, in post
path, data=data, format=format, content_type=content_type, **extra)
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/test.py", line 89, in post
data, content_type = self._encode_data(data, format, content_type)
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/test.py", line 64, in _encode_data
ret = renderer.render(data)
File "/vagrant/venv/lib/python3.4/site-packages/rest_framework/renderers.py", line 757, in render
return encode_multipart(self.BOUNDARY, data)
File "/vagrant/venv/lib/python3.4/site-packages/django/test/client.py", line 182, in encode_multipart
return b'\r\n'.join(lines)
TypeError: sequence item 4: expected bytes, bytearray, or an object with the buffer interface, str found
检查这是否解决了您的问题,因为错误清楚地表明数据不应是列表
data = {"account_csv": open('accounts/importer/accounts.csv'), "apartments_csv": open('accounts/importer/apartments.csv')}
您可能会发现此链接很有用您正在将文件列表发送到视图,但发送不正确。当您向视图发送数据时,无论是Django视图还是DRF视图,都应该以键值对列表的形式发送数据
{
"key": "value",
"file": open("/path/to/file", "rb"),
}
要回答你的问题
有可能吗
似乎不可能使用同一个键(在测试中)上载多个文件,但可以将它们分散到多个键以实现相同的目标。或者,您可以将视图设置为只处理一个文件,并有多个测试覆盖不同的测试用例(plants.csv
,accounts.csv
,等等)
正在触发您的异常,因为您传递的是单个列表而不是字典,Django无法正确解析它们
直接生成请求字典可能会带来一些运气,它是Django使用的表单数据的内部表示形式
data = QueryDict(mutable=True)
data.setlist("files", [
open('accounts/importer/accounts.csv', 'rb'),
open('accounts/importer/apartments.csv', 'rb')
])
因为这将更紧密地表示通过浏览器发送的数据。这还没有经过测试,但这是一种在一个键中发送多个非文件值的方法。猜测很好,但您的答案绕过了实际问题:使用表单数据发送的任何数据必须是一组键值对。同意@Kevin。只是想给OP一些提示来摆脱这个问题。抱歉@MaNKuR,也尝试过了,但我得到了类似
TypeError:sequence item 4:expected bytes,bytearray,或者一个带有缓冲区接口的对象,str发现了@chachan尝试以二进制形式读取文件,查看我的更新答案。这很有效!,我必须str(content)
在后端,但我可以接受。谢谢!