Django注册报错:'str' object has no attribute 'get' 求助
Django注册报错:'str' object has no attribute 'get' 解决方法
问题描述
注册用户时触发错误,错误信息为:
AttributeError: 'str' object has no attribute 'get'
错误追踪指向表单验证阶段,调用form.is_valid()时,Django尝试访问cleaned_data.get()但cleaned_data被替换成了字符串类型。
错误原因
问题出在RegisterForm的clean方法:你在方法最后返回了password2(字符串类型),而Django要求clean方法必须返回完整的cleaned_data字典。当返回字符串后,后续代码将其当作cleaned_data使用,调用.get()方法自然触发属性错误。
修复步骤
修改RegisterForm的clean方法,返回父类clean方法的结果(即完整的cleaned_data字典):
class RegisterForm(forms.ModelForm): username = forms.CharField(max_length=100, label='用户名') password1 = forms.CharField(max_length=100, label='密码', widget=forms.PasswordInput) password2 = forms.CharField(max_length=100, label='确认密码', widget=forms.PasswordInput) class Meta: model = User fields = ['username', 'password1', 'password2'] def clean(self): password1 = self.cleaned_data.get('password1') password2 = self.cleaned_data.get('password2') if password1 and password2 and password1 != password2: raise forms.ValidationError('两次输入的密码不一致!') # 返回完整的cleaned_data字典,而非单个字符串 return super().clean()
额外优化建议
1. UserProfile必填字段问题
你的UserProfile模型中name、surname、bio为必填字段,但信号创建UserProfile时仅传入user=instance,未提供这些字段值,会导致创建用户时触发数据库错误。可二选一解决:
- 将字段设为可选:
class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) username = models.CharField(verbose_name='用户名', max_length=40, blank=True) # 可省略,User已有username字段 name = models.CharField(verbose_name='名字', max_length=40, blank=True, null=True) surname = models.CharField(verbose_name='姓氏', max_length=40, blank=True, null=True) bio = models.TextField(blank=True, null=True) avatar = models.ImageField(null=True, blank=True)
- 或者在注册表单中添加对应字段,让用户填写后同步保存到UserProfile。
2. 信号关联名称问题
save_profile信号中instance.profile.save()需确保关联名称正确。默认OneToOneField的related_name为模型名小写(即userprofile),可修改信号或设置related_name:
# 方案1:修改信号代码 @receiver(post_save, sender=User) def save_profile(sender, instance, **kwargs): instance.userprofile.save() # 方案2:在UserProfile中设置related_name class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') # ...其他字段...
错误详情
- 请求方法:POST
- 请求URL:http://127.0.0.1:8000/accounts/register
- Django版本:4.1.3
- Python版本:3.11.0
- 异常类型:AttributeError
- 异常信息:'str' object has no attribute 'get'
关键追踪栈:
File ".../views.py", line 19, in Register_view if form.is_valid(): File ".../forms.py", line 422, in _get_validation_exclusions field_value = self.cleaned_data.get(field)
内容的提问来源于stack exchange,提问作者Sub
相关产品推荐
相关产品推荐

