Django运行表单测试时报MultiValueKeyError:'district'错误如何解决
错误原因
- 表单
clean_email方法直接读取未校验的原始请求数据self.data['district'],一旦district参数缺失或未通过字段校验,就会抛出键不存在的异常。 - 测试用例未提交所有必填字段:你继承的
UserCreationForm默认自带password1、password2两个必填密码字段,加上代码里声明的first_name、last_name、paper、district都是必填项,仅传email和district也会因为其他字段缺失导致表单校验异常。 - 原有测试的状态码断言逻辑错误:表单校验通过后会走重定向逻辑,返回状态码是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
相关产品推荐
相关产品推荐

