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 %}标签自动生成匹配路由的路径,不会出现斜杠多漏的问题。
测试写法正确性说明
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测试的标准写法。
- 方案1:直接修改请求URL,删除末尾斜杠:
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
相关产品推荐
相关产品推荐

