Django扩展User模型字段无法保存至MongoDB问题求助
问题:Django扩展User模型后额外字段无法保存到MongoDB
问题详情
扩展Django内置User模型,添加了company_name和role字段,但通过注册表单创建用户时,这两个字段无法保存到MongoDB数据库。提交表单后用户能正常创建,且表单已正确捕获这些字段(通过打印form.cleaned_data确认),但数据库文档中没有这两个字段。
用户提供的代码如下:
forms.py
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from django.contrib.auth.models import User from django import forms from django.forms.widgets import PasswordInput, TextInput from django.core.exceptions import ValidationError class CreateUserForm(UserCreationForm): company_name = forms.CharField(max_length=100) role = forms.CharField(max_length=100) email = forms.EmailField(required=True) def clean_email(self): email = self.cleaned_data.get('email') if email and email.endswith('@gmail.com'): raise ValidationError("Gmail addresses are not allowed.") return email class Meta: model = User fields = ['username', 'email','company_name', 'role', 'password1', 'password2'] def save(self, commit=True): user = super(CreateUserForm, self).save(commit=False) user.company_name = self.cleaned_data['company_name'] user.role = self.cleaned_data['role'] if commit: user.save() return user class LoginForm(AuthenticationForm): username = forms.CharField(widget=TextInput()) password = forms.CharField(widget=PasswordInput())
views.py
from django.shortcuts import render, redirect from . forms import CreateUserForm, LoginForm from django.contrib.auth.decorators import login_required from django.contrib.auth.models import auth from django.contrib.auth import authenticate, login, logout def homepage(request): return render(request, 'loginapp/index.html') def signupPage(request): form = CreateUserForm() if request.method == "POST": form = CreateUserForm(request.POST) if form.is_valid(): print("Form data:", form.cleaned_data) form.save() return redirect("loginPage") context = {'registerform':form} return render(request, 'loginapp/signupPage.html', context=context) def loginPage(request): form = LoginForm() if request.method == 'POST': form = LoginForm(request, data=request.POST) if form.is_valid(): username = request.POST.get('username') password = request.POST.get('password') user = authenticate(request, username=username, password=password) if user is not None: auth.login(request, user) return redirect("dashboard") context = {'loginform':form} return render(request, 'loginapp/loginPage.html', context=context) def user_logout(request): auth.logout(request) return redirect("") @login_required(login_url="loginPage") def dashboard(request): return render(request, 'loginapp/dashboard.html')
原因分析
核心问题在于:你的表单仍然绑定了Django默认的User模型,而非你自己扩展的用户模型。
默认User模型并没有company_name和role字段,即使你在表单中添加了这些字段并赋值给user对象,Django ORM也不会将这些未在模型中定义的字段保存到数据库(包括MongoDB)。这就是为什么数据库文档中看不到这两个字段的原因。
解决方案
需要创建自定义用户模型并配置Django使用该模型,步骤如下:
1. 创建自定义用户模型
在应用的models.py中定义继承AbstractUser的自定义用户模型,添加所需字段:
from django.contrib.auth.models import AbstractUser from django.db import models class CustomUser(AbstractUser): company_name = models.CharField(max_length=100) role = models.CharField(max_length=100)
2. 配置Django使用自定义用户模型
在项目的settings.py中添加以下配置(替换为你的应用名):
AUTH_USER_MODEL = 'loginapp.CustomUser'
注意:该配置必须在执行第一次
migrate前设置。如果已经执行过迁移,需要重置数据库(删除现有迁移文件和数据库)后重新执行迁移。
3. 修改表单绑定自定义模型
更新forms.py,使用get_user_model()获取自定义用户模型,避免硬编码:
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm from django.contrib.auth import get_user_model from django import forms from django.forms.widgets import PasswordInput, TextInput from django.core.exceptions import ValidationError # 获取自定义用户模型 User = get_user_model() class CreateUserForm(UserCreationForm): email = forms.EmailField(required=True) def clean_email(self): email = self.cleaned_data.get('email') if email and email.endswith('@gmail.com'): raise ValidationError("Gmail addresses are not allowed.") return email class Meta: model = User fields = ['username', 'email','company_name', 'role', 'password1', 'password2'] def save(self, commit=True): user = super().save(commit=False) user.email = self.cleaned_data['email'] # 显式赋值额外字段(可选,因为fields中已包含,super().save会自动处理) user.company_name = self.cleaned_data['company_name'] user.role = self.cleaned_data['role'] if commit: user.save() return user class LoginForm(AuthenticationForm): username = forms.CharField(widget=TextInput()) password = forms.CharField(widget=PasswordInput())
4. 执行数据库迁移
运行以下命令创建并应用迁移:
python manage.py makemigrations python manage.py migrate
验证
重新运行项目,提交注册表单后,MongoDB中的用户文档应该会包含company_name和role字段。
内容的提问来源于stack exchange,提问作者Huzaifa
相关产品推荐
相关产品推荐

