Skip to main content
 首页 » 编程设计

python之Django REST 框架 : error when testing POST request with list

2024年09月03日39lyj

我有一个测试 View :

@api_view(['POST']) 
@permission_classes([AllowAny]) 
@authentication_classes([]) 
def test_view(request): 
    return Response(request.data) 

在urls.py中注册:

urlpatterns = [ 
    path('api/test/', test_view) 
] 

当我尝试通过 REST Frameworks UI 手动发布 [{"a": 1}, {"a": 2}] 时,一切正常。

但是,如果我为其编写测试,则会发生意外错误。这是测试

from rest_framework.test import APITestCase 
 
class ViewTest(APITestCase): 
    def test_it(self): 
        response = self.client.post('/api/test/', [{"a": 1}, {"a": 2}]) 
        print(response) 

产生以下错误:

Traceback (most recent call last): 
  File "C:\development\HeedView\backend\clients\api\tests.py", line 13, in test_it 
    response = self.client.post('/api/test/', [{"a":1}, {"a": 2}]) 
  File "C:\development\HeedView\venv\lib\site-packages\rest_framework\test.py", line 300, in post 
    path, data=data, format=format, content_type=content_type, **extra) 
  File "C:\development\HeedView\venv\lib\site-packages\rest_framework\test.py", line 212, in post 
    data, content_type = self._encode_data(data, format, content_type) 
  File "C:\development\HeedView\venv\lib\site-packages\rest_framework\test.py", line 184, in _encode_data 
    ret = renderer.render(data) 
  File "C:\development\HeedView\venv\lib\site-packages\rest_framework\renderers.py", line 921, in render 
    return encode_multipart(self.BOUNDARY, data) 
  File "C:\development\HeedView\venv\lib\site-packages\django\test\client.py", line 194, in encode_multipart 
    for (key, value) in data.items(): 
AttributeError: 'list' object has no attribute 'items' 

如何解释这种行为?

请您参考如下方法:

传递json数据需要加上format='json'。这个测试有效:

from rest_framework.test import APITestCase 
 
class ViewTest(APITestCase): 
    def test_it(self): 
        response = self.client.post('/api/test/', [{"a": "1"}, {"a": 2}], format='json') 
        print(response.json()) 

或者,如果您set the default format,您的原始测试有效在 settings.py 中:

REST_FRAMEWORK = { 
    ... 
    'TEST_REQUEST_DEFAULT_FORMAT': 'json' 
} 

如果未指定格式:

Rest Framework APIClient扩展 Django 现有的 Client 类。 documentation for Client.post解释说:

The key-value pairs in the data dictionary are used to submit POST data. For example:

... client.post('/login/', {'name': 'fred', 'passwd': 'secret'})

... [tests] this POST data:

name=fred&passwd=secret

您的原始测试返回一个错误,因为如果未指定格式,则 Django 需要一个字典,而不是一个列表。