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

Django视图测试返回403/200而非预期302的问题排查

Django论坛视图测试失败解决方案

一、创建主题测试返回200(预期302)

原因

表单验证未通过,导致页面重新渲染而非重定向。常见触发场景:

  • AddTopicForm包含subject/first_comment以外的必填字段,但测试请求未传递
  • 测试复用了已有主题的subject,若表单对标题设置了唯一约束则验证失败
  • 请求数据类型与表单字段要求不匹配

修复方案

  1. 检查AddTopicForm定义,确保测试数据覆盖所有必填字段。若标题需唯一,更换测试用的主题标题:
def test_add_topic(self):
    data = {
        'subject': '全新测试主题',  # 使用未重复的标题
        'first_comment': self.topic.first_comment
    }
    url = reverse("forum:add_topic", kwargs={'subforum_slug': self.subforum.slug})
    old_topics_count = Topic.objects.count()
    response = self.client.post(url, data=data)

    self.assertEqual(response.status_code, 302)
    self.assertEqual(Topic.objects.count(), old_topics_count + 1)
  1. 可添加表单错误断言定位具体问题:
self.assertFormError(response, 'form', 'subject', '该主题标题已存在')  # 根据实际错误信息调整

二、编辑主题测试返回200(预期302)

原因

UpdateFirstComment复用了AddTopicForm,而该表单要求subject为必填字段,但测试请求仅传递了first_comment,导致表单验证失败,页面重新渲染。

修复方案

在测试请求中补充必填的subject字段:

def test_update_first_comment(self):
    data = {
        'subject': self.topic.subject,  # 补充表单必填的主题标题
        'first_comment': "Chebuldyk"
    }
    url = reverse("forum:edit_topic", kwargs={
        'subforum_slug': self.subforum.slug,
        'topic_slug': self.topic.slug
    })
    old_first_comment = self.topic.first_comment
    response = self.client.post(url, data=data)
    self.topic.refresh_from_db()

    self.assertEqual(response.status_code, 302)
    self.assertNotEqual(self.topic.first_comment, old_first_comment)

若编辑场景不需要修改标题,建议专门创建编辑表单,移除subject的必填约束,避免复用添加表单带来的冗余验证。

三、删除主题测试返回403(预期302)

原因

DeleteTopic的test_func仅允许超级用户执行删除,但测试中登录的是普通用户(factories.UserFactory()默认创建非超级用户),权限校验不通过,返回403。

修复方案

有两种调整方向:

  1. 修改测试用例:将测试用户设置为超级用户
def setUp(self):
    self.subforum = factories.SubForumFactory()
    self.user = factories.UserFactory(is_superuser=True)  # 创建超级用户
    self.topic = factories.TopicFactory(subforum=self.subforum, creator=self.user)
    self.client.force_login(self.user)
  1. 调整视图权限逻辑:允许主题创建者删除自己的主题
class DeleteTopic(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    # ... 其余代码不变
    def test_func(self):
        topic = self.get_object()
        return self.request.user.is_superuser or self.request.user == topic.creator

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:33:17