You need to enable JavaScript to run this app. Django视图测试返回404而非302的测试方案合理性咨询
优惠活动
大模型
产品
解决方案
定价
更多

Django视图测试返回404而非302的测试方案合理性咨询

故障根因

你遇到的404问题和POST参数无关,核心是测试请求的URL和路由定义不匹配:
路由配置中路径为 exercise/<int:ex_pk>/edl/<int:unit_pk>/convert 末尾无斜杠,而测试代码中请求的URL是 f'/exercise/{ex.pk}/edl/{unit.pk}/convert/' 末尾多了斜杠,Django路由匹配严格区分末尾斜杠,因此直接返回404。线上功能正常是因为模板调用时使用{% url %}标签自动生成匹配路由的路径,不会出现斜杠多漏的问题。

测试写法正确性说明

  1. URL写法错误需要修正
    有两种修正方案,更推荐第二种:

    • 方案1:直接修改请求URL,删除末尾斜杠:
      response = self.client.post(f'/exercise/{ex.pk}/edl/{unit.pk}/convert')
      
    • 方案2:使用Django内置reverse函数生成URL,避免手写路径出错:
      from django.urls import reverse
      
      # 测试代码中生成URL
      url = reverse('generate-edl', kwargs={'ex_pk': ex.pk, 'unit_pk': unit.pk})
      response = self.client.post(url)
      
      这种方式不受路由路径字符串修改的影响,只要路由的name属性不变,生成的URL永远正确,是Django测试的标准写法。
  2. POST参数写法正确
    你的视图确实不需要额外POST参数,不传POST数据字典是完全合法的。Django测试框架的client默认禁用CSRF校验,即使不传递csrfmiddlewaretoken也可以正常发起POST请求,不需要额外调整。

代码优化建议

当前代码可以正常运行,不需要大的重构,可做几个小优化提升健壮性和测试准确性:

  • 用get_object_or_404替代直接Model.objects.get(),当传入的ex_pk/unit_pk不存在时返回标准404响应,而非抛出500异常:
    from django.shortcuts import get_object_or_404
    
    ex_instance = get_object_or_404(Exercises, id=ex_pk)
    unit_instance = get_object_or_404(Units, id=unit_pk)
    
  • 视图中硬编码的Locations.objects.get(location="Okinawa")建议抽成常量或者提前做异常处理,避免定位值变更后触发异常。
  • POST逻辑处理完成后可增加成功提示,优化用户体验。
  • 调整测试逻辑,先清空测试表数据再发起请求,确保测试结果真实反映视图的执行效果:
    def test_generate_edl(self):
        # 先清空已有数据,排除手动创建数据的干扰
        ExerciseEdl.objects.all().delete()
        url = reverse('generate-edl', kwargs={'ex_pk': ex.pk, 'unit_pk': unit.pk})
        response = self.client.post(url)
        ex_edl = ExerciseEdl.objects.all().count()
        self.assertEquals(ex_edl, 2)
        self.assertEqual(response.status_code, 302)
    

内容的提问来源于stack exchange,提问作者merryfistmas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 11:24:08