如何解决Django使用AbstractUser注册时报save()缺少self参数的错误
问题原因及解决方法
核心报错原因
你视图代码中存在一行错误的冗余调用:在执行CustomUser.objects.create_user()之后,又写了CustomUser.save(commit=False),这就是报错的直接诱因:
create_user方法本身已经完成了用户实例创建、密码自动哈希、数据入库的全流程,不需要额外调用保存方法save()是模型实例的方法,不能直接用模型类CustomUser调用,这行代码直接删除即可。
登录失败的解决方法
1. 清理模型层重复字段
你继承的AbstractUser已经内置了id、first_name、last_name、username、email、password这些基础字段,重复定义会引发未知异常,尤其是你自定义的password字段长度和官方默认长度不符,会导致哈希后的密码存储异常,直接把这些重复字段从CustomUser类中删除即可。
2. 补充自定义用户模型配置
你需要在项目settings.py中添加如下配置,指定Django使用你自定义的用户模型做鉴权:
AUTH_USER_MODEL = "你的应用名称.CustomUser"
如果没有这行配置,Django默认会用内置的官方User表做登录校验,你注册的用户存在自定义的CustomUser表里,自然无法完成登录。
修改后的代码示例
views.py
def signup(request): if request.method == 'POST': first_name = request.POST['first-name'] last_name = request.POST['last-name'] username = request.POST['username'] email = request.POST['email'] phone_no = request.POST['phone-no'] password = request.POST['password'] password2 = request.POST['password2'] if password==password2: if CustomUser.objects.filter(username=username).exists(): messages.info(request, '用户名已被占用') return redirect('signup') elif CustomUser.objects.filter(email=email).exists(): messages.info(request, '邮箱已被注册') return redirect('signup') else: CustomUser.objects.create_user( first_name=first_name, last_name=last_name, username=username, email=email, phone_no=phone_no, password=password ) return redirect('login') else: messages.info(request, '两次输入的密码不一致') return redirect('signup') else: return render(request, 'signup.html')
models.py
class CustomUser(AbstractUser): phone_no = models.CharField(max_length=20) is_end_user = models.BooleanField(default=True) is_smart_earner = models.BooleanField(default=False) is_top_user = models.BooleanField(default=False)
最后操作
修改完成后需要重新生成迁移文件并执行迁移:
python manage.py makemigrations python manage.py migrate
如果之前已经生成过用户表的迁移记录,需要先删除对应应用下migrations文件夹中除了__init__.py之外的所有文件,同时删除数据库中的旧用户表后再执行迁移,避免字段冲突。
内容的提问来源于stack exchange,提问作者Royal_Devs
相关产品推荐
相关产品推荐

