Django 3.2.9重写表单save方法触发The given username must be set错误如何解决
Django 3.2.9 重写表单save方法报ValueError问题排查
问题现象
使用Django 3.2.9开发项目时,重写表单save方法出现如下报错:
ValueError The given username must be set from form self
不重写save方法时,视图中直接调用保存功能运行正常;重写后表单无法读取self属性,但表单类内其他校验方法可以正常读取self属性。
相关代码
自定义注册表单类代码
class RegisterForm(forms.Form): username=forms.CharField( required=True, min_length=4,max_length=50, widget=TextInput(attrs={ 'class':'form-control' }) ) email=forms.EmailField( required=True, min_length=4,max_length=50, widget=TextInput(attrs={ 'class':'form-control' }) ) pwd=forms.CharField( required=True, min_length=4,max_length=50, widget=PasswordInput(attrs={ 'class':'form-control' }) ) pwdr=forms.CharField( required=True, min_length=4,max_length=50, widget=PasswordInput(attrs={ 'class':'form-control' }) ) def clean_username(self): username=self.cleaned_data.get('username') if User.objects.filter(username=username).exists(): raise forms.ValidationError('该用户名已被使用') return username def clean_email(self): email=self.cleaned_data.get('email') if User.objects.filter(email=email).exists(): raise forms.ValidationError('该邮箱已被使用') return email def clean(self): cleaned_data=super().clean() if cleaned_data.get('pwd')!= cleaned_data.get('pwdr'): self.add_error('pwdr','两次输入的密码不一致') return redirect('register') return redirect('home') def save(self): username=self.cleaned_data.get('username') email=self.cleaned_data.get('email') pwd=self.cleaned_data.get('pwd') return User.objects.create_user( username, email, pwd )
问题排查
save方法内打印self的结果为表单渲染后的HTML片段:
label for="id_username">Username:
Email: Pwd: Pwdr:
查阅Django官方文档发现相关说明:
注意:调用Form.add_error()方法时会自动将相关字段从cleaned_data中移除。
问题根源
clean方法写法不符合Django表单校验规范:
- 全局clean方法仅需处理校验逻辑,校验通过时返回
cleaned_data即可,不需要返回redirect响应 - 校验不通过时抛出ValidationError即可,不需要调用add_error后返回redirect响应
错误的返回逻辑导致cleaned_data未被正确传递,后续save方法读取cleaned_data中的字段时得到None,最终触发ValueError。
修复方案
修改clean方法为如下写法即可:
def clean(self): cleaned_data = super().clean() pwd = cleaned_data.get('pwd') pwdr = cleaned_data.get('pwdr') if pwd != pwdr: raise forms.ValidationError('两次输入的密码不一致') return cleaned_data
内容的提问来源于stack exchange,提问作者user11319165
相关产品推荐
相关产品推荐

