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

Django 4.1.1自定义用户模型登录功能失效的解决方法

Django 4.1.1自定义用户模型登录无响应问题解决指导

问题说明

我正在使用Django 4.1.1开发教育网站,已创建继承AbstractUser的Student自定义用户模型,注册功能可正常将用户数据存入数据库,但登录功能完全无响应,既不跳转也不返回错误。请指导如何实现能验证用户输入数据与数据库匹配并完成登录的功能。

现有代码

models.py

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


class Custom(UserManager):
    def create_user(self, username, email=None, password=None, **extra_fields):
        return self._create_user(username, email, password, **extra_fields)


class Student(AbstractUser):

    objects = Custom()

    sex = models.CharField(max_length=50,default='male')
    is_superuser = None
    is_staff = None  
    groups = None
    user_permissions = None


    class Meta:
        verbose_name = "Student"
        verbose_name_plural = "Students" 


    def __str__(self):
        return self.username

注册表单HTML

{% load static %}

<html>


<link rel="stylesheet" href="{% static 'css/register.css' %}">
<form  method="post">
    {% csrf_token %}
    
    <input type="text" name="firstName" placeholder="First Name" required minlength="3" maxlength="30">
    <input type="text" name="lastName" placeholder="Last Name" required minlength="3" maxlength="30">
    <input type="text" name="username" placeholder="Username" required minlength="3" maxlength="30">
    <small>{{error}}</small>
    <input type="email" name="email" placeholder="Email" required maxlength="64">
    <small>{{error}}</small>
    <input type="password" name="password" placeholder="Password" required minlength="8" maxlength="32">
    <input type="password" name="passwordAgain" placeholder="Confirm Password" required minlength="8" maxlength="32">
    <small>{{paswword_error}}</small>
    <input type="radio" name="sex" value="male" checked>Male</input>
    <input type="radio" name="sex" value="female">Female</input>
    
    <button type="submit">Submit</button>

</form>
<script src="{% static 'js/register.js' %}"></script>
</html>

views.py

from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import Student
from django.contrib.auth import authenticate,login,logout

# Create your views here.


def home(request):
    # return HttpResponse('This is The Home Page !')
    return render(request, 'home/index.html')




def register(request):
    if request.method == 'POST':

        firstName = request.POST['firstName']
        lastName = request.POST['lastName']
        username = request.POST['username']
        email = request.POST['email']
        password = request.POST['password']
        passwordAgain = request.POST['passwordAgain']
        sex = request.POST['sex']
        
        if Student.objects.filter(username=username).exists() or Student.objects.filter(email=email).exists() or password != passwordAgain:
            error = "Alrady Taken"
            paswword_error = "Paswwords Don't Match"
            return render(request,'register/register.html',{'error':error,'paswword_error':paswword_error})
        else:

            user = Student.objects.create_user(username,email,password)
            user.first_name = firstName
            user.last_name = lastName
            user.sex = sex
            user.save()
            return redirect('login')        


    return render(request,'register/register.html')



def login(request):

    if request.method == 'Post':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request,username=username,password=password)
        if user is not None:
            login(request,user)
            return redirect('home')
        else:
            return HttpResponse('error')

    return render(request, 'login/login.html')

问题排查与修复步骤

1. 视图函数名与内置函数冲突

你导入了django.contrib.auth中的login函数,但同时定义了同名的视图函数def login(request):,这会导致调用login(request, user)时实际调用的是你自己的视图函数,而非Django内置的登录认证函数,直接引发错误。

修复:将视图函数名改为user_login(或其他不冲突的名称),同时更新URL配置中的对应路由名称。

2. 请求方法判断大小写错误

Django中请求方法均为大写,代码中request.method == 'Post'的判断永远不会成立,导致POST请求进来后直接走渲染模板的分支,没有执行登录逻辑。

修复:将判断条件改为request.method == 'POST'。

3. 未配置自定义用户模型

使用自定义用户模型时,必须在settings.py中指定AUTH_USER_MODEL,否则Django的认证系统会默认使用原生User模型,导致authenticate无法正确识别你的Student用户。

修复:在settings.py中添加:

AUTH_USER_MODEL = '你的应用名.Student'  # 替换成实际的应用名称

4. 登录表单完整性检查

确保登录模板(login/login.html)的表单结构正确:

  • 表单method设为post
  • 包含{% csrf_token %}标签
  • 用户名和密码输入框的name属性分别为username和password

示例登录模板:

{% load static %}
<html>
<link rel="stylesheet" href="{% static 'css/login.css' %}">
<form method="post">
    {% csrf_token %}
    <input type="text" name="username" placeholder="Username" required>
    <input type="password" name="password" placeholder="Password" required>
    {% if login_error %}
        <small>{{ login_error }}</small>
    {% endif %}
    <button type="submit">Login</button>
</form>
</html>

5. 完善错误返回逻辑

原代码中错误时直接返回HttpResponse('error'),用户体验差,建议将错误信息传入模板展示。

修改后的完整views.py代码

from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import Student
from django.contrib.auth import authenticate, login, logout

# Create your views here.

def home(request):
    return render(request, 'home/index.html')

def register(request):
    if request.method == 'POST':
        firstName = request.POST['firstName']
        lastName = request.POST['lastName']
        username = request.POST['username']
        email = request.POST['email']
        password = request.POST['password']
        passwordAgain = request.POST['passwordAgain']
        sex = request.POST['sex']
        
        error = None
        paswword_error = None
        if Student.objects.filter(username=username).exists() or Student.objects.filter(email=email).exists():
            error = "用户名或邮箱已被占用"
        if password != passwordAgain:
            paswword_error = "两次输入的密码不一致"
        if error or paswword_error:
            return render(request,'register/register.html',{'error':error,'paswword_error':paswword_error})
        
        user = Student.objects.create_user(username, email, password)
        user.first_name = firstName
        user.last_name = lastName
        user.sex = sex
        user.save()
        return redirect('user_login')        

    return render(request,'register/register.html')

def user_login(request):
    login_error = None
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect('home')
        else:
            login_error = "用户名或密码错误"
    return render(request, 'login/login.html', {'login_error': login_error})

最后更新URL配置

确保URL路由中,登录对应的名称改为user_login:

# urls.py示例
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('register/', views.register, name='register'),
    path('login/', views.user_login, name='user_login'),
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:45:22