Django自定义用户模型执行makemigrations时字段错误求助
解决Django自定义用户模型时的password1/password2字段错误
问题根源
password1和password2是Django表单层用来做密码确认的字段,不该放到数据库模型里。AbstractUser本身已经自带了加密的password字段,你在自定义模型里重复定义这两个字段属于冗余操作,而且会导致Django混淆字段归属。
分步解决
1. 修正models.py
删掉自定义模型里的password1和password2字段,只保留你的业务自定义字段:
# models.py from django.contrib.auth.models import AbstractUser from django.db import models class RemittanceUser(AbstractUser): # 示例自定义字段,根据你的需求修改 phone_number = models.CharField(max_length=15, unique=True) # 移除 password1 和 password2 字段
2. 确认settings.py配置
必须指定Django使用你的自定义用户模型,否则Django会默认用内置的User模型,导致字段不匹配:
# settings.py # 替换成你的app名称,比如如果app叫users,就写'users.RemittanceUser' AUTH_USER_MODEL = 'your_app_name.RemittanceUser'
注意:如果已经执行过默认User模型的migrate操作,需要重置数据库(删除db.sqlite3或清空数据库),否则会出现表冲突。
3. 在表单层处理密码验证
密码确认逻辑应该放到表单里,而不是模型。推荐两种方式:
方式一:复用UserCreationForm
Django自带的UserCreationForm已经内置了password1和password2的验证逻辑,直接继承即可:
# forms.py from django.contrib.auth.forms import UserCreationForm from .models import RemittanceUser class RemittanceUserCreationForm(UserCreationForm): class Meta: model = RemittanceUser # 这里只需要列出你的自定义字段,password1/password2会自动包含 fields = ('username', 'phone_number', 'email')
方式二:自定义表单
如果需要更灵活的验证逻辑,自己写表单:
# forms.py from django import forms from .models import RemittanceUser from django.contrib.auth.hashers import make_password class RemittanceUserForm(forms.ModelForm): password1 = forms.CharField(label='密码', widget=forms.PasswordInput(attrs={'placeholder': '请输入密码'})) password2 = forms.CharField(label='确认密码', widget=forms.PasswordInput(attrs={'placeholder': '请再次输入密码'})) class Meta: model = RemittanceUser fields = ('username', 'phone_number', 'email') def clean_password2(self): # 验证两次密码一致 password1 = self.cleaned_data.get('password1') password2 = self.cleaned_data.get('password2') if password1 and password2 and password1 != password2: raise forms.ValidationError('两次密码输入不一致') return password2 def save(self, commit=True): # 将密码加密后存入模型的password字段 user = super().save(commit=False) user.password = make_password(self.cleaned_data['password1']) if commit: user.save() return user
4. 重新生成迁移文件
如果之前生成过错误的迁移文件,先删除app下migrations目录中除了__init__.py之外的所有文件,然后执行:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者Rufaro Mutepfa
相关产品推荐
相关产品推荐

