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

Django运行表单测试时报MultiValueKeyError:'district'错误如何解决

错误原因
  1. 表单clean_email方法直接读取未校验的原始请求数据self.data['district'],一旦district参数缺失或未通过字段校验,就会抛出键不存在的异常。
  2. 测试用例未提交所有必填字段:你继承的UserCreationForm默认自带password1、password2两个必填密码字段,加上代码里声明的first_name、last_name、paper、district都是必填项,仅传email和district也会因为其他字段缺失导致表单校验异常。
  3. 原有测试的状态码断言逻辑错误:表单校验通过后会走重定向逻辑,返回状态码是302而非200,只有校验失败时才会返回200渲染表单页面。
修复步骤

第一步:修正表单校验逻辑

将clean_email方法中读取district的逻辑改为读取已校验的cleaned_data,同时增加空值判断:

def clean_email(self):
    value = self.cleaned_data.get("email")
    # 先从已校验数据中取district,不存在直接抛出错误
    value_district = self.cleaned_data.get("district")
    if not value:
        raise forms.ValidationError('请填写邮箱地址。')
    if not value_district:
        raise forms.ValidationError('请选择所属学区。')
    check_users = CustomUser.objects.filter(email__iexact=value)
    if check_users:
        raise forms.ValidationError('该邮箱已被注册。')
    if not self.check_suffix(value, value_district):
        self.add_error("email", "您的邮箱域名与所选学区不匹配。")
    return value

第二步:补全测试用例的必填参数

修改测试代码,提交所有必填字段,同时修正状态码断言:

def test_signup_endpoint(self):
    test_data = {
        'email': 'foo@vsb.bc.ca',
        'district': 'SD39',
        'first_name': '测试',
        'last_name': '用户',
        'paper': True,
        'password1': 'TestPass123!',
        'password2': 'TestPass123!'
    }
    result = self.client.post('/accounts/signup/', test_data)
    # 校验通过后会重定向到激活提示页,状态码为302
    self.assertEqual(result.status_code, 302)
    created_user = get_user_model().objects.get(email='foo@vsb.bc.ca')
    self.assertFalse(created_user.is_active)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:57:00