前言: Django 内置的 Auth(用户认证)组件,是后端开发中"用户登录、注册、注销、权限控制"的"万能工具",无需手动搭建用户表、密码加密、Session 管理,开箱即用。
目标: 本文从「核心原理」到「项目完整落地」,结合实际项目场景,手把手教你吃透 Auth 组件,代码可直接复制运行,适合 Django 新手快速上手。
本文适配场景: Django 2.x/3.x/4.x 版本,基于实际项目(front 应用)演示,包含「表单校验+Auth 认证+前端模板+路由配置」全流程,解决新手常见的"密码明文存储""登录后回跳""未登录无法访问页面"等问题。
一、Auth 组件核心原理
1.1 核心作用
Auth 组件本质是 Django 内置的"用户认证系统",封装了 4 大核心功能,无需重复开发:
-
用户注册:提供加密创建用户的方法,避免密码明文存储
-
用户登录:校验账号密码、自动写入 Session、维护登录状态
-
用户注销:清空 Session,重置登录状态
-
权限控制:通过装饰器,限制"必须登录才能访问"的页面
1.2 核心依赖
使用 Auth 组件无需额外安装,Django 默认自带,只需导入两个核心模块:
# 1. 认证核心模块(负责登录、注销、校验)
from django.contrib import auth
# 2. 用户模型(自动生成 auth_user 数据表,存储用户信息)
from django.contrib.auth.models import User
1.3 关键注意点(避坑首选)
-
禁止用 User.objects.create() 创建用户(密码明文存储,无法登录);
-
必须执行数据库迁移,生成 auth_user 表(否则无法存储用户);
-
登录校验分两步:先 authenticate() 校验账号密码,再 login() 写入状态;
-
未登录跳转需配置 LOGIN_URL,否则装饰器会报错。
二、Auth 核心用法
2.1 创建用户(3种方法,重点掌握前2种)
Auth 提供 3 种创建用户的方法,核心区别是"密码是否加密"和"是否为超级用户",直接复制代码即可使用:
from django.contrib.auth.models import User
# 方法1:创建普通用户(密码密文存储,推荐用于前端注册)
User.objects.create_user(
username="zhangsan", # 用户名(必填,唯一)
password="123456", # 密码(自动加密)
email="zhangsan@qq.com" # 邮箱(可选)
)
# 方法2:创建超级用户(可登录 Django Admin 后台,必填邮箱)
User.objects.create_superuser(
username="admin",
password="admin123",
email="admin@163.com" # 必须传邮箱,否则报错
)
# 方法3:create() 方法(不推荐,密码明文存储,无法登录)
# User.objects.create(username="test", password="123") # 错误示范
2.2 用户登录(authenticate + login)
登录流程:获取前端提交的账号密码 → 用 authenticate() 校验 → 校验通过用 login() 写入 Session → 跳转到首页/来源页。
核心说明:
-
authenticate(username, password):校验成功返回用户对象,失败返回 None;
-
auth.login(request, user_obj):无返回值,作用是"写入 Session,将 request.user 赋值为当前用户";
-
next 参数:记录用户未登录时的访问地址,登录后自动回跳(用户体验优化)。
from django.shortcuts import render, redirect
from django.contrib import authdef login_view(request):
# GET 请求:返回登录页面
if request.method == "GET":
return render(request, "login.html")# POST 请求:处理登录逻辑 username = request.POST.get("username") # 前端表单name属性值 password = request.POST.get("pwd") # 前端表单name属性值 # 1. 校验账号密码 user_obj = auth.authenticate(username=username, password=password) # 校验失败:返回登录页,提示错误信息 if not user_obj: return render(request, "login.html", {"msg": "用户名或密码错误"}) # 2. 校验成功:写入登录状态 auth.login(request, user_obj) # 3. 登录后回跳(优先回跳之前访问的页面,否则跳首页) next_url = request.GET.get("next") or "/index/" return redirect(next_url)
2.3 用户注销(logout)
注销逻辑:清空 Session 信息,将 request.user 重置为匿名用户,无需复杂操作,一行代码搞定。
from django.shortcuts import redirect
from django.contrib import auth
def logout_view(request):
# 清空登录状态(无返回值)
auth.logout(request)
# 注销后跳回登录页
return redirect("/login/")
2.4 权限控制(login_required 装饰器)
场景:首页、个人中心、留言板等页面,需要"用户登录后才能访问",未登录自动跳转到登录页。
使用步骤:导入装饰器 → 给需要控制的视图函数添加装饰器 → 配置 LOGIN_URL(未登录跳转地址)。
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
# 装饰器:未登录自动跳转到 LOGIN_URL 配置的地址
@login_required
def index(request):
# 登录后,可通过 request.user 获取当前用户信息
current_user = request.user
return render(request, "index.html", {"user": current_user})
配置 LOGIN_URL(项目根目录 settings.py 末尾添加):
# Auth 未登录跳转地址(必须配置,否则装饰器报错)
LOGIN_URL = "/login/"
2.5 常用用户判断 & 属性
登录后,可通过 request.user 快速获取当前用户信息,常用操作如下:
# 判断用户是否已登录(返回 True/False)
request.user.is_authenticated
# 获取当前用户用户名
request.user.username
# 获取当前用户邮箱
request.user.email
# 获取当前用户ID
request.user.id
# 判断是否为超级用户
request.user.is_superuser
总结
| Auth 功能 | 实现位置 | 关键代码 |
|---|---|---|
| 创建用户 | register_view | User.objects.create_user() |
| 用户登录 | login_view | auth.authenticate() + auth.login() |
| 用户注销 | logout_view | auth.logout() |
| 权限控制 | @login_required | @login_required(login_url='login') |
| 用户信息 | 模板和 shell | request.user.xxx |
三、项目完整落地(实战核心,直接复制)
本实战基于「front 应用」演示,包含「表单校验+Auth 认证+前端模板+路由配置」全流程,完全贴合实际项目,保留原有业务逻辑(如留言板),新增 Auth 认证功能。
3.1 项目环境准备
-
确认项目已创建 front 应用(若未创建,执行命令):
python manage.py startapp front
-
配置 settings.py(启用 Auth 组件+注册 front 应用):
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth', # Auth 核心组件(默认存在,不要删除)
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'front', # 注册自己的应用
]新增:未登录跳转地址
LOGIN_URL = "/login/"
-
执行数据库迁移(生成 auth_user 表):
3.2 完善 forms.py(表单校验,对接 Auth)
包含「注册表单」(手机号校验、密码二次校验)和「留言板表单」(保留原有业务),直接替换 front/forms.py 代码:
from django import forms
from django.core import validators
from django.contrib.auth.models import User # 导入 Auth 用户模型
from .models import Message # 导入自己的留言板模型(若有)
# 留言板表单(保留原有业务,无需修改)
class MessageBoardForm(forms.ModelForm):
class Meta:
model = Message
fields = ['title', 'content', 'email']
labels = {
'title': '留言标题',
'content': '留言内容',
'email': '联系邮箱',
}
widgets = {
'content': forms.Textarea(attrs={'rows': 6, 'placeholder': '请输入留言内容'}),
}
error_messages = {
'title': {
'min_length': '标题最小长度不能少于2个字符!',
'max_length': '标题最大长度不能超过20个字符!',
},
'email': {
'invalid': '邮箱格式不正确!',
}
}
# 注册表单(对接 Auth,新增校验逻辑)
class RegisterForm(forms.Form):
telephone = forms.CharField(
label='手机号',
validators=[validators.RegexValidator(r'^1[3456789]\d{9}$', message='手机号格式不符合要求!')],
widget=forms.TextInput(attrs={'placeholder': '请输入11位手机号'})
)
username = forms.CharField(
label='用户名',
min_length=3,
max_length=20,
widget=forms.TextInput(attrs={'placeholder': '请输入3-20位用户名'})
)
pwd1 = forms.CharField(
label='密码',
min_length=6,
max_length=100,
widget=forms.PasswordInput(attrs={'placeholder': '请输入6-100位密码'})
)
pwd2 = forms.CharField(
label='确认密码',
min_length=6,
max_length=100,
widget=forms.PasswordInput(attrs={'placeholder': '请再次输入密码'})
)
# 局部钩子:校验手机号是否已注册(避免重复注册)
def clean_telephone(self):
telephone = self.cleaned_data.get('telephone')
# 手机号存到 User 表的 username 字段(User 无手机号字段)
if User.objects.filter(username=telephone).exists():
raise forms.ValidationError("该手机号已被注册!")
return telephone
# 全局钩子:校验两次密码是否一致
def clean(self):
cleaned_data = super().clean()
pwd1 = cleaned_data.get('pwd1')
pwd2 = cleaned_data.get('pwd2')
if pwd1 != pwd2:
self.add_error('pwd2', '两次输入的密码不一致!')
return cleaned_data
3.3 编写 views.py(视图逻辑,整合 Auth)
包含「首页、注册、登录、注销、留言板」5个核心视图,直接复制到 front/views.py:
from django.shortcuts import render, redirect
from django.contrib import auth
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from .forms import RegisterForm, MessageBoardForm
from .models import Message
# 1. 首页(必须登录才能访问)
@login_required
def index(request):
# 登录后,通过 request.user 获取当前用户信息
return render(request, 'index.html', {'user': request.user})
# 2. 注册视图(对接 RegisterForm + Auth 创建用户)
def register(request):
if request.method == 'GET':
# GET 请求:返回注册页面,渲染表单
form = RegisterForm()
return render(request, 'register.html', {'form': form})
# POST 请求:处理注册逻辑,校验表单
form = RegisterForm(request.POST)
if form.is_valid():
# 拿到表单清洗后的数据
username = form.cleaned_data.get('username')
telephone = form.cleaned_data.get('telephone')
password = form.cleaned_data.get('pwd1')
# 核心:用 Auth 方法创建加密用户(禁止用 create())
User.objects.create_user(
username=username, # 用户名
password=password, # 加密密码
email=telephone # 手机号存到邮箱字段(可选)
)
# 注册成功,跳转到登录页
return redirect('/login/')
# 表单校验失败:返回注册页,展示错误信息
return render(request, 'register.html', {'form': form})
# 3. 登录视图(Auth 标准写法,支持回跳)
def login_view(request):
if request.method == 'GET':
return render(request, 'login.html')
# 获取前端提交的账号密码
username = request.POST.get('username')
password = request.POST.get('pwd')
# 校验账号密码
user_obj = auth.authenticate(username=username, password=password)
if not user_obj:
return render(request, 'login.html', {'msg': '用户名或密码错误'})
# 写入登录状态
auth.login(request, user_obj)
# 登录后回跳
next_url = request.GET.get('next') or '/index/'
return redirect(next_url)
# 4. 注销视图
def logout_view(request):
auth.logout(request) # 清空登录状态
return redirect('/login/')
# 5. 留言板视图(必须登录才能留言,新增权限控制)
@login_required
def message_board(request):
if request.method == 'GET':
form = MessageBoardForm()
messages = Message.objects.all().order_by('-create_time')
return render(request, 'message_board.html', {'form': form, 'messages': messages})
form = MessageBoardForm(request.POST)
if form.is_valid():
form.save()
return redirect('/message_board/')
messages = Message.objects.all().order_by('-create_time')
return render(request, 'message_board.html', {'form': form, 'messages': messages})
3.4 配置 urls.py(路由映射)
配置 front/urls.py,映射所有视图,直接复制:
from django.urls import path
from . import views
urlpatterns = [
# 首页
path('index/', views.index, name='index'),
# 注册
path('register/', views.register, name='register'),
# 登录
path('login/', views.login_view, name='login'),
# 注销
path('logout/', views.logout_view, name='logout'),
# 留言板
path('message_board/', views.message_board, name='message_board'),
]
补充:若项目根目录 urls.py 未包含 front 应用路由,需添加(否则无法访问):
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('front.urls')), # 包含 front 应用路由
]
3.5 编写前端模板(templates 文件夹)
在 front 应用下创建 templates 文件夹,新建 4 个 HTML 文件,直接复制代码,支持表单错误提示、登录状态展示。
1. login.html(登录页面)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<style>
.container { width: 400px; margin: 100px auto; }
.error { color: red; margin-bottom: 10px; }
input { width: 100%; padding: 8px; margin: 5px 0; }
button { width: 104%; padding: 10px; background: #007bff; color: white; border: none; border-radius: 4px; }
a { display: block; text-align: center; margin-top: 10px; color: #007bff; text-decoration: none; }
</style>
</head>
<body>
<div class="container">
<h2 style="text-align: center;">用户登录</h2>
{% if msg %}
<div class="error">{{ msg }}</div>
{% endif %}
<form action="" method="post">
{% csrf_token %} {# Django 防跨站请求伪造,必须加 #}
<label>用户名:</label>
<input type="text" name="username" required placeholder="请输入用户名"><br>
<label>密码:</label>
<input type="password" name="pwd" required placeholder="请输入密码"><br>
<button type="submit">登录</button>
<a href="/register/">还没有账号?去注册</a>
</form>
</div>
</body>
</html>
2. register.html(注册页面)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
<style>
.container { width: 400px; margin: 80px auto; }
.error { color: red; font-size: 12px; }
input { width: 100%; padding: 8px; margin: 5px 0; }
button { width: 104%; padding: 10px; background: #28a745; color: white; border: none; border-radius: 4px; }
a { display: block; text-align: center; margin-top: 10px; color: #007bff; text-decoration: none; }
</style>
</head>
<body>
<div class="container">
<h2 style="text-align: center;">用户注册</h2>
<form action="" method="post">
{% csrf_token %}
{# 自动渲染表单,包含错误提示 #}
{{ form.as_p }}
<button type="submit">注册</button>
<a href="/login/">已有账号?去登录</a>
</form>
</div>
</body>
</html>
3. index.html(登录后首页)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>首页</title>
<style>
.container { width: 800px; margin: 50px auto; text-align: center; }
a { margin: 0 10px; color: #007bff; text-decoration: none; }
.logout { color: #dc3545; }
</style>
</head>
<body>
<div class="container">
<h1>欢迎 {{ user.username }} 登录系统!</h1>
<p>当前登录用户:{{ user.username }} | 邮箱:{{ user.email }}</p>
<div>
<a href="/message_board/">去留言板</a>
<a href="/logout/" class="logout">退出登录</a>
</div>
</div>
</body>
</html>
4. message_board.html(留言板页面)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>留言板</title>
<style>
.container { width: 800px; margin: 50px auto; }
.form-box { margin-bottom: 30px; padding: 20px; border: 1px solid #eee; border-radius: 4px; }
.message { margin: 10px 0; padding: 10px; border-bottom: 1px solid #eee; }
.title { font-weight: bold; }
.content { margin: 5px 0; }
.email { font-size: 12px; color: #666; }
a { color: #007bff; text-decoration: none; }
</style>
</head>
<body>
<div class="container">
<h2>留言板</h2>
<a href="/index/">返回首页</a>
<div class="form-box">
<h3>发表留言</h3>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">提交留言</button>
</form>
</div>
<div class="message-list">
<h3>留言列表</h3>
{% for msg in messages %}
<div class="message">
<div class="title">{{ msg.title }}</div>
<div class="content">{{ msg.content }}</div>
<div class="email">联系邮箱:{{ msg.email }}</div>
</div>
{% empty %}
<div>暂无留言,快来发表第一条留言吧!</div>
{% endfor %}
</div>
</div>
</body>
</html>
3.6 启动项目测试(完整流程)
执行启动命令,按照以下顺序测试,确保所有功能正常:
python manage.py runserver

-
访问注册页:http://127.0.0.1:8000/register/,测试表单校验(手机号格式、密码长度、两次密码一致);
-
注册成功后,自动跳转到登录页,输入账号密码登录;
-
登录后跳转到首页,可看到当前用户信息,点击"去留言板"发表留言;
-
未登录状态下,直接访问 http://127.0.0.1:8000/index/,会自动跳转到登录页;
-
点击"退出登录",回到登录页,再次访问首页会被拦截。
现在可以直接访问:
| 功能 | 新 URL |
|---|---|
| 📝 注册 | http://127.0.0.1:8000/register/ ✅ |
| 🔐 登录 | http://127.0.0.1:8000/login/ ✅ |
| 💬 首页 | http://127.0.0.1:8000/ ✅ |
| 📄 发布文章 | http://127.0.0.1:8000/article/ ✅ |
🧪 完整测试流程
- 打开浏览器访问 http://127.0.0.1:8000/register/
- 填写注册信息 :
- 用户名:test123
- 邮箱:test@example.com
- 密码:password123
- 确认密码:password123
- 点击"注册"按钮 → 重定向到登录页
- 输入刚才的账户登录 → 成功显示首页,看到用户名和注销按钮
- 尝试访问 /article/ → 可以正常发布文章
- 点击"注销"按钮 → 清空会话,重定向到登录页
- 再次访问 /article/ → 被重定向到登录页 ✅








在 SSMS 中查询这三个数据
1. 查询用户表 auth_user(test123)
USE django_form_demo;
SELECT id, username, email, date_joined
FROM auth_user;

2. 查询留言板表 front_message(刚才发的帖子)
USE django_form_demo;
SELECT id, title, content, email, create_time
FROM front_message;
3.在 SSMS 查询文章表 front_article
USE django_form_demo;
SELECT id, title, content, category, create_time
FROM front_article;

或者查看所有字段:
USE django_form_demo;
SELECT *
FROM front_article
ORDER BY create_time DESC;
四、常见问题&解决方案
| 常见问题 | 解决方案 |
|---|---|
| 创建用户后,登录提示"用户名或密码错误" | 1. 检查是否用了 create() 方法(改用 create_user());2. 确认密码输入正确;3. 执行数据库迁移 |
| @login_required 装饰器报错 | 在 settings.py 中添加 LOGIN_URL = "/login/",确保路由正确 |
| 注册时手机号无法重复校验 | 检查 clean_telephone 钩子函数,确保过滤的是 User 表的 username 字段(手机号存于此) |
| 登录后无法回跳之前的页面 | 确保登录视图中添加了 next_url = request.GET.get("next") or "/index/",并 redirect(next_url) |
| 前端表单提交报 403 Forbidden | 表单中忘记添加 {% csrf_token %} 标签,添加即可解决 |
五、总结
Django Auth 组件的核心优势是"封装完善、开箱即用",无需手动处理密码加密、Session 管理等繁琐操作,重点掌握以下 5 点,就能应对绝大多数项目的用户认证需求:
-
创建用户:用 create_user()(普通用户)、create_superuser()(超级用户);
-
登录流程:authenticate() 校验 → login() 写入状态;
-
注销流程:logout() 清空状态;
-
权限控制:@login_required 装饰器 + LOGIN_URL 配置;
-
用户信息:登录后通过 request.user 获取。
本文所有代码均可直接复制运行,适配 Django 2.x/3.x/4.x 版本,若需扩展功能(如自定义用户模型、密码重置),可在评论区留言,后续补充。






