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

如何在Django自定义UserAuthentication模型中校验用户是否存在

问题原因

  1. Django默认的authenticate认证方法会读取内置auth.User表,没有配置自定义用户模型的前提下不会查询你写的UserAuthentication表
  2. 现有UserAuthentication直接继承models.Model,没有兼容Django认证体系的基础字段和方法,无法和自带的authenticate、login方法适配
  3. 视图中if user is UserAuthentication逻辑错误:is用于判断两个对象的内存地址是否一致,user是用户实例,UserAuthentication是模型类,二者永远不相等
  4. 密码明文存储在password1字段中,authenticate方法默认会将传入的密码做哈希加密后和数据库存储的哈希值对比,明文密码永远无法通过校验

修复步骤

1. 修改自定义用户模型(models.py)

继承Django提供的AbstractBaseUser和PermissionsMixin获得认证体系兼容能力,删除冗余的明文密码字段,新增用户管理器:

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
from django.db import models

class UserManager(BaseUserManager):
    def create_user(self, username, email, password=None, **extra_fields):
        if not username:
            raise ValueError('用户名必须填写')
        if not email:
            raise ValueError('邮箱必须填写')
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(username, email, password, **extra_fields)

class UserAuthentication(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=100, unique=True, verbose_name="用户名")
    email = models.EmailField(unique=True, verbose_name="邮箱")
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()
    # 指定用户名字段,authenticate方法会用该字段匹配用户
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    def __str__(self):
        return self.username

2. 配置settings.py指定自定义用户模型

添加配置项,告知Django使用你定义的用户表替换内置User表,替换代码中你的应用名为实际存放UserAuthentication模型的app名称:

AUTH_USER_MODEL = '你的应用名.UserAuthentication'

3. 修改视图逻辑(views.py)

修正用户判断逻辑:

def loginpage(request):
   if request.method == "POST":
       username = request.POST.get('username')
       password = request.POST.get('password')
       user = authenticate(request, username=username, password=password)
       if user is not None:
           login(request, user)
           return redirect('index')
       else:
           messages.warning(request, "用户名或密码错误!")
           return redirect('login')
   else:
       return render(request, "HTML/login.html", context={})

4. 数据迁移与注意事项

  • 修改完用户模型后需要删除之前的迁移文件和数据库文件,重新执行python manage.py makemigrations和python manage.py migrate,避免迁移冲突
  • 注册逻辑中校验两次密码一致后,调用user.set_password(明文密码)方法加密存储密码,不要直接给password字段赋值明文
  • 原有明文存储的旧用户数据需要重新创建,否则无法通过密码校验

内容的提问来源于stack exchange,提问作者Subhan Malik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:27:03