Django自定义用户模型提交表单后无法保存至数据库
问题排查:Django自定义用户模型前端注册不保存用户
Admin页面功能正常,但前端提交注册表单后返回302重定向,用户未存入数据库且无报错,问题出在以下几处:
1. forms.py字段定义错误
last_name字段少了调用括号,导致它是类引用而非实例,表单验证会静默失败:
错误代码:
last_name = forms.CharField
修复后:
last_name = forms.CharField()
2. CustomUserManager的create_user方法参数缺失
create_user方法强制要求first_name、last_name等参数,但未接收表单中存在的username字段;同时save()时未指定数据库连接,可能导致保存失败;超级用户创建时调用create_user缺少必填参数,会引发隐性错误。
修改后的CustomUserManager:
import datetime from django.db import models from django.contrib.auth.models import AbstractUser from django.contrib.auth.base_user import BaseUserManager from django.utils.translation import gettext_lazy as _ class CustomUserManager(BaseUserManager): def create_user(self, email, password=None, username=None, first_name='', last_name='', birth_date=None, credit_card=0, **extra_fields): if not email: raise ValueError(_('The Email must be set')) email = self.normalize_email(email) # 处理username默认值,避免参数缺失 user = self.model( username=username or email.split('@')[0], email=email, first_name=first_name, last_name=last_name, birth_date=birth_date or datetime.date.today(), credit_card=credit_card, **extra_fields ) user.set_password(password) # 指定数据库连接确保保存生效 user.save(using=self._db) return user def create_superuser(self, email, password, **extra_fields): extra_fields.setdefault("is_staff", True) extra_fields.setdefault("is_superuser", True) extra_fields.setdefault("is_active", True) if extra_fields.get("is_staff") is not True: raise ValueError(_("Superuser must have is_staff=True.")) if extra_fields.get("is_superuser") is not True: raise ValueError(_("Superuser must have is_superuser=True.")) # 补充超级用户创建所需的必填参数 return self.create_user( email=email, password=password, first_name='Admin', last_name='User', **extra_fields ) class CustomUser(AbstractUser): birth_date = models.DateField(default=datetime.date.today) credit_card = models.IntegerField(default=0) objects = CustomUserManager()
3. views.py重定向逻辑错误
当前代码不管表单是否验证通过,都会直接重定向,导致验证失败时也跳转到test页面;同时redirect(test)应使用URL名称或字符串路径,而非直接传入视图函数:
错误代码:
if request.POST: form = RegisterUserForm(request.POST) if form.is_valid(): form.save() return redirect(test)
修复后:
from django.shortcuts import render, redirect from .forms import RegisterUserForm from django.http import HttpResponse def register_user(request): if request.method == 'POST': form = RegisterUserForm(request.POST) if form.is_valid(): form.save() # 使用字符串路径或URL名称重定向 return redirect('/test/') # 验证失败时返回表单页面,显示错误信息 return render(request, 'accounts/index.html', {'form': form}) else: form = RegisterUserForm() return render(request, 'accounts/index.html', {'form': form}) def test(request): return HttpResponse('TEST!')
额外优化:简化表单定义
RegisterUserForm无需重复定义email、first_name等字段,AbstractUser已包含这些字段,只需在Meta中指定字段即可:
from django.contrib.auth.forms import UserCreationForm from .models import CustomUser class RegisterUserForm(UserCreationForm): class Meta: model = CustomUser fields = ('username', 'first_name', 'last_name', 'email', 'birth_date', 'credit_card', 'password1', 'password2')
完成以上修改后,前端表单提交时会正确验证字段,验证通过后用户将被保存到数据库,验证失败则显示对应错误信息。
内容的提问来源于stack exchange,提问作者Maddin S.
相关产品推荐
相关产品推荐

