You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Django APIClient发送POST请求时遇404错误求助

问题:DRF测试用例POST请求返回404,但Postman调用正常

我使用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手动调用正常。


排查与解决方案

  1. 测试数据库无目标数据
    测试用例运行时使用独立的测试数据库,和Postman调用的开发/生产数据库不共享数据。你代码里硬编码获取id=43的WordModel实例,但测试数据库中大概率没有这条数据,因此触发DoesNotExist异常返回404。

    • 解决:在测试类的setUp()方法中创建对应id=43的WordModel实例,或者用工厂类(如factory_boy)生成测试数据。
  2. 请求路径不完整或错误
    测试用例中硬编码的wordOftheDay/可能缺少URL前缀(比如项目配置了/api/前缀),导致请求路径无效。

    • 解决:使用Django的reverse()方法生成正确URL,避免硬编码错误。示例:
      from django.urls import reverse
      
      def test_valid_post_request(self):
          # ...
          response = client.post(reverse('wordOftheDay'), self.valid_data, format='json')
          # ...
      
      前提是你在URL配置中给该端点设置了name='wordOftheDay'。
  3. 视图变量名错误导致逻辑分支异常
    视图中的判断条件使用了未定义的变量:你从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:33:19