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

Django中用email作为用户名登录失败,user返回None求解决

Django自定义用户模型登录失败问题排查与解决

问题描述

我是Django新手,开发项目时创建了tblusuarios数据库表,插入了姓名、姓氏、邮箱、密码等数据。尝试用邮箱作为用户名登录时始终失败,视图里的user变量一直返回None。已经在自定义用户模型中设置USERNAME_FIELD='correo',但问题仍未解决。

相关代码

自定义用户模型

class TblUsuarios(AbstractBaseUser, models.Model):
    nombre = models.CharField(max_length=80)
    apellidos = models.CharField(max_length=80, blank=True, null=True)
    correo = models.CharField(max_length=80, unique=True)
    telefono = models.CharField(max_length=11, blank=True, null=True)
    password = models.CharField(max_length=80)
    foto = models.ImageField(upload_to='images/')
    tbl_roles = models.ForeignKey(TblRoles, models.DO_NOTHING, default=1)

    # object = CustomAccountManager()
    USERNAME_FIELD = 'correo'
    REQUIRED_FIELDS=(['nombre'])
    class Meta:
        db_table = 'tbl_usuarios'

视图函数

def login_user(request):
    if request.method == 'POST':
        correo = request.POST['email']
        password = request.POST['password']

        user = authenticate(request, username = correo, password = password)
        print(user)
        if user is not None:
            login(request, user)
            messages.info(request, 'Has ingresado correctamente a la aplicacion!!')
            return redirect('home')
        else:
            messages.error(request, 'Ha ocurrido un error a la hora de iniciar sesion!')
            return redirect('login')
    else:
        context = {}
        return render(request, 'users/login.html', context)

登录表单

{% extends "layouts/layout.html" %} {% block content %}

{% if user.is_authenticated %}
    <h2>Ya estas logueado en nuestra aplicación</h2>
{% else %}

<section class="vh-100">
  <div class="container-fluid">
    <div class="row">
      <div class="col-sm-6 text-black">
        <div
          class="d-flex align-items-center h-custom-2 px-5 ms-xl-4 mt-5 pt-5 pt-xl-0 mt-xl-n5"
        >
          <form style="width: 23rem" method="post" action="">
              {% csrf_token %}
            <h3 class="fw-normal mb-3 pb-3" style="letter-spacing: 1px">
              Log in
            </h3>

            <div class="form-outline mb-4">
              <input
                type="email"
                id="email"
                class="form-control form-control-lg"
                name="email"
              />
              <label class="form-label" for="email"
                >Correo</label
              >
            </div>

            <div class="form-outline mb-4">
              <input
                type="password"
                id="password"
                class="form-control form-control-lg"
                name="password"
              />
              <label class="form-label" for="password">Contraseña</label>
            </div>
            
            <div class="pt-1 mb-4">
                <input type="submit" value="Ingresar"  class="btn btn-info btn-lg btn-block">
            </div>

            <p class="small mb-5 pb-lg-2">
              <a class="text-muted" href="#!">Olvidaste tu contraseña?</a>
            </p>
            <p>
              No tienes una cuenta?
              <a href="/register/" class="link-info">Registrate acá</a>
            </p>
          </form>
        </div>
      </div>
      <div class="col-sm-6 px-0 d-none d-sm-block">
        <img
          src="https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-login-form/img3.webp"
          alt="Login image"
          class="w-100 vh-100"
          style="object-fit: cover; object-position: left"
        />
      </div>
    </div>
  </div>
</section>
{% endif %}
{% endblock content %}

问题排查与解决方案

  • 移除自定义的password字段:AbstractBaseUser已内置password字段并自动处理哈希,手动定义的password = models.CharField(max_length=80)会覆盖内置字段,导致明文存储无法验证,直接删除该行。
  • 启用并实现自定义用户管理器:使用AbstractBaseUser必须配套自定义管理器,取消注释objects = CustomAccountManager(),并添加管理器代码:
from django.contrib.auth.base_user import BaseUserManager

class CustomAccountManager(BaseUserManager):
    def create_user(self, correo, nombre, password=None, **extra_fields):
        if not correo:
            raise ValueError('El correo debe ser proporcionado')
        correo = self.normalize_email(correo)
        user = self.model(correo=correo, nombre=nombre, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, correo, nombre, password=None, **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 debe tener is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser debe tener is_superuser=True')

        return self.create_user(correo, nombre, password, **extra_fields)
  • 更新用户密码为哈希格式:之前插入的明文密码无法验证,通过Django shell重新设置:
from your_app.models import TblUsuarios
user = TblUsuarios.objects.get(correo='你的测试邮箱')
user.set_password('你的密码')
user.save()
  • 配置AUTH_USER_MODEL:在settings.py中指定自定义用户模型:
AUTH_USER_MODEL = 'your_app.TblUsuarios'

替换your_app为实际应用名称,该配置需在项目初始化时设置,若已创建数据库需重新迁移。

完成以上步骤后,重新运行迁移并测试登录功能即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:54:58