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

Django中无法将表单数据存入数据库且出现'type object 'UserRegister' has no attribute 'USERNAME_FIELD''错误

Django中无法将表单数据存入数据库且出现'type object 'UserRegister' has no attribute 'USERNAME_FIELD''错误

我看到你遇到了两个头疼的问题:表单数据存不进数据库,还抛出了type object 'UserRegister' has no attribute 'USERNAME_FIELD'的错误。让我帮你一步步排查修复:

错误核心原因

这个错误的根源是你的UserRegister模型继承了普通的models.Model,但你使用的UserCreationForm是Django专门为继承AbstractUser的自定义用户模型设计的表单类。AbstractUser内置了USERNAME_FIELD等用户认证必需的属性,而普通Model没有这些,所以才会触发这个报错。


1. 修复models.py

把UserRegister改成继承AbstractUser,这是Django自定义用户模型的标准做法:

from django.contrib.auth.models import AbstractUser
from django.db import models

class UserRegister(AbstractUser):
    # 如果你不需要额外的用户字段,这里可以留空
    # AbstractUser已经包含了username、email、password等核心字段
    class Meta:
        verbose_name = "User Register" 
        verbose_name_plural = "User Register" 

    # 不需要自己写save方法处理密码加密,AbstractUser会自动完成
    def __str__(self):
        return self.username

必须配置的一步:在项目的settings.py里指定自定义用户模型:

AUTH_USER_MODEL = '你的APP名称.UserRegister'  # 替换成你实际的app名字,比如'accounts.UserRegister'

注意:如果是新项目,建议清空数据库后重新执行makemigrations和migrate;如果是已有数据的项目,需要做数据迁移兼容(新手推荐新项目清空重来)。


2. 修复forms.py

现在模型继承了AbstractUser,表单可以简化,UserCreationForm会自动处理很多基础逻辑:

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.core.exceptions import ValidationError
from .models import UserRegister

class UserRegisterForm(UserCreationForm):
    username = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={'placeholder': 'Username', 'class': 'input-group'}))
    email = forms.EmailField(max_length=70, required=True, widget=forms.EmailInput(attrs={'placeholder': 'Email', 'class': 'input-group'}))
    password1 = forms.CharField(max_length=128, required=True, widget=forms.PasswordInput(attrs={'placeholder': 'Password', 'class': 'input-group', 'id': 'password'}))
    password2 = forms.CharField(max_length=128, required=True, widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password', 'class': 'input-group', 'id': 'confirm_password'}))

    class Meta:
        model = UserRegister
        fields = ['username', 'email', 'password1', 'password2']

    def clean_email(self):
        email = self.cleaned_data.get('email')
        if UserRegister.objects.filter(email=email).exists():
            raise ValidationError('This email address is already in use.')
        return email

    # 以下两个方法可以删除:
    # 1. clean_username:AbstractUser已经默认username是唯一的,UserCreationForm会自动验证
    # 2. clean:UserCreationForm已经内置了密码一致性验证

小细节:之前你给password1和password2的widget都用了id="password",会导致DOM元素ID重复,我把确认密码的ID改成了confirm_password,避免前端冲突。


3. 修复views.py

之前手动创建用户的方式不仅麻烦,还可能导致密码重复加密的问题,现在用表单的save()方法更规范:

from django.shortcuts import render
from django.http import HttpResponseRedirect ,Http404
from .forms import UserRegisterForm
from django.contrib import messages

# 保留你的products列表和其他视图函数不变

def Login(request):
    if request.method == "POST":
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            # 直接调用form.save(),自动完成用户创建和密码加密
            form.save()
            messages.success(request, 'Your account has been created!')
            return HttpResponseRedirect('/Products')
        else:
            print("Form is not valid")
            print(form.errors)
    else:
        form = UserRegisterForm()
    return render(request, 'login.html', {'form': form})

之前手动实例化UserRegister的方式,会导致密码被你的模型save方法再次加密,最终用户登录时密码验证失败,用form.save()就完全避免了这个问题。


4. 修复login.html的小问题

你之前把表单的action设为/Products,其实应该提交到当前的注册视图,然后由视图重定向到Products,所以可以把action留空:

<form method="POST" action="">
    {% csrf_token %}
    <!-- 保留其他表单内容不变 -->
</form>

另外按钮文本是Sign In(登录),但这是注册页面,改成Sign Up(注册)会更符合用户预期,这是细节优化~


备注:内容来源于stack exchange,提问作者Hardik Jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:24:29