使用Django APIClient发送POST请求时遇404错误求助
我使用rest_framework.test.APIClient编写Django REST Framework API的测试用例,尝试向wordOftheDay/端点发送带指定数据的POST请求,但持续收到404错误。运行单元测试时,代码直接执行except块,未进入try块,但通过Postman手动调用该API却能得到200 OK响应。
测试用例代码
def test_valid_post_request(self): client = APIClient() print(client) response = client.post('wordOftheDay/', self.valid_data, format='json') print('response',response) self.assertEqual(response.status_code, 200) print('response.status_code',response.status_code) # Check if the model is created with the expected data self.assertTrue(WordModel.objects.filter(device_id=self.valid_data['device_id']).exists())
补充API视图POST方法代码
def post(self, request, **kwargs): #d_param = request.query_params.get('d') d_type = request.data.get('d_type') o_version = request.data.get('o_version') d_id = request.data.get('d_id') w_family = request.data.get('w_family') if device_type is not None and os_version is not None and device_id is not None and widget_family is not None: device_analytics = { 'd_type' : d_type, 'o_version' : o_version, 'd_id' : d_id, 'w_family' : w_family, } self.updateDA(device_analytics, d_id, w_family) try: # #current_date = date.today() # current_date = '2023-10-21' # date_string = str(current_date) # valid_date = datetime.strptime(date_string, '%Y-%m-%d').date() # # if valid_date: # # word_instance = WordModel.objects.get(date=valid_date) # serializer = WordSerializers(word_instance) word_instance = WordModel.objects.get(id=43) serializer = WordSerializers(word_instance) return Response(serializer.data, status=status.HTTP_200_OK) except WordModel.DoesNotExist: return Response({"error": "Data for the given date does not exist"}, status=status.HTTP_404_NOT_FOUND)
我已注释try块原逻辑,简化为返回特定记录,但执行python manage.py test wordOfTheDay.tests.test_wordOfTheDay时仍收到404错误(响应信息:{"error":"Data for the given date does not exist"}),而Postman手动调用正常。
排查与解决方案
测试数据库无目标数据
测试用例运行时使用独立的测试数据库,和Postman调用的开发/生产数据库不共享数据。你代码里硬编码获取id=43的WordModel实例,但测试数据库中大概率没有这条数据,因此触发DoesNotExist异常返回404。- 解决:在测试类的
setUp()方法中创建对应id=43的WordModel实例,或者用工厂类(如factory_boy)生成测试数据。
- 解决:在测试类的
请求路径不完整或错误
测试用例中硬编码的wordOftheDay/可能缺少URL前缀(比如项目配置了/api/前缀),导致请求路径无效。- 解决:使用Django的
reverse()方法生成正确URL,避免硬编码错误。示例:
前提是你在URL配置中给该端点设置了from django.urls import reverse def test_valid_post_request(self): # ... response = client.post(reverse('wordOftheDay'), self.valid_data, format='json') # ...name='wordOftheDay'。
- 解决:使用Django的
视图变量名错误导致逻辑分支异常
视图中的判断条件使用了未定义的变量:你从request.data中取出的是d_type、o_version、d_id、w_family,但判断时用的是device_type、os_version、device_id、widget_family,这些变量未定义,条件必然不成立,后续try块不会执行?但你收到的是404,说明代码进入了except块,可能是你实际代码中的变量名是正确的,但测试用例的self.valid_data缺少必要字段。- 解决:
- 修正视图中的变量名,将判断条件改为:
if d_type is not None and o_version is not None and d_id is not None and w_family is not None: - 检查
self.valid_data是否包含d_type、o_version、d_id、w_family这四个必填字段。
- 修正视图中的变量名,将判断条件改为:
- 解决:
内容的提问来源于stack exchange,提问作者jessiepinkman

