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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:20:41