Django Session权限管理实战:登录、校验与登出全流程解析
本文详细解析Django中利用Session进行权限管理的完整流程。从配置urls路由开始,通过models定义用户模型,在views中实现登录状态校验、表单数据验证及Session写入,最后通过登出函数清空Session。文章涵盖未登录跳转、重复登录拦截及Session状态判断等核心逻辑,帮助开发者快速构建安全的用户认证系统。
启用Session功能后,传递给视图函数的HttpRequest对象将自动包含一个session属性,其行为类似于字典。开发者可以在Django项目的任意位置通过request.session属性进行读写操作,或多次调用该属性来管理会话数据。
本文示例代码所在的本地路径为C:\Users\17764530215\test\mysite。
1. urls.py路由配置
from django.contrib import admin
from django.urls import path
from login import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('login/', views.login),
path('register/', views.register),
path('logout/', views.logout),
]

权限控制策略如下:
- 未登录用户访问index、login或logout页面时,均强制重定向至login界面。
- 已登录用户访问login页面时,自动重定向至index首页。
- 已登录用户禁止直接访问register注册页面,必须先执行logout登出操作。
- 用户执行登出操作后,自动重定向至login登录界面。
(上述逻辑即构成了完整的功能闭环)
2. login/models.py模型定义
from django.db import models
# Create your models here.
class User(models.Model):
gender = (
('male', "男"),
('female', "女"),
)
name = models.CharField(max_length=128, unique=True)
password = models.CharField(max_length=256)
email = models.EmailField(unique=True)
sex = models.CharField(max_length=32, choices=gender, default="男")
c_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Meta:
ordering = ["-c_time"]
verbose_name = "用户"
verbose_name_plural = "用户"
各字段具体含义说明:
name字段为必填项,最大长度128个字符,且设置unique=True确保姓名唯一;password字段为必填项,最大长度256个字符(实际业务中可能无需如此长);email字段使用Django内置的EmailField类型,并设置unique=True保证邮箱唯一;sex字段为性别选项,使用choices限制只能选择男或女,默认值为男;通过__str__方法实现对象的人性化显示;在Meta元数据中定义ordering为['-c_time'],即按创建时间倒序排列,最新注册用户优先显示。
3. views.login视图与login.html模板交互
views.login逻辑如下:
def login(request):
if request.session.get('is_login', None): # 不允许重复登录
return redirect('/index/')
if request.method == 'POST':
login_form = forms.UserForm(request.POST) #上一次填写了这个表单,所以从这里得到这个表单的数据
message = '请检查填写的内容!'
if login_form.is_valid():
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
try:
user = models.User.objects.get(name=username)
except :
message = '用户不存在!'
return render(request, 'login/login.html', locals())
if user.password == password: #如果用户名和密码都成功
# 往session字典内写入用户状态和数据:
request.session['is_login'] = True #is_login=True表示成功登陆
request.session['user_id'] = user.id
request.session['user_name'] = user.name
return redirect('/index/') #重定向到主页
else:
message = '密码不正确!'
return render(request, 'login/login.html', locals())
else:
return render(request, 'login/login.html', locals())
# 不是POST的话,统统转去login.html
login_form = forms.UserForm()
return render(request, 'login/login.html', locals())
用户进入login页面时,首先检查session中是否存在is_login键且值为True。若存在,说明用户已登录,直接重定向至/index/首页。
若session中is_login为False或不存在,即用户未登录,则继续执行后续逻辑。若请求方法为POST,则执行表单验证及相关业务操作;若为GET请求,则表示用户首次访问login页面,此时实例化forms.UserForm生成login_form对象,并将其作为参数传递给login/login.html模板进行渲染。
若session中is_login为False且请求方法为POST,说明用户已提交表单,此处涉及核心业务逻辑与Session管理。若login_form.is_valid()验证通过,即通过login_form = forms.UserForm(request.POST)获取表单数据后,与数据库中的用户名和密码进行比对。验证成功后,将request.session['is_login']设置为True以标记登录状态,同时记录user_id和user_name字段数据,供后续使用。
接下来分析login/login.html模板部分。
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- 上述meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<!-- Bootstrap CSS -->
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<title>登录</title>
</head>
<body>
<div class="container">
<div class="col">
<form class="form-login" action="/login/" method="post">
{% if message %}
<div class="alert alert-warning">{{ message }}</div>
{% endif %}
{% csrf_token %}
<h3 class="text-center">欢迎登录</h3>
{{ login_form }}
<div>
<a href="/register/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="text-success " ><ins>新用户注册</ins></a>
<button type="submit" class="btn btn-primary float-right">登录</button>
</div>
</form>
</div>
</div> <!-- /container -->
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
{# 以下三者的引用顺序是固定的#}
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script src="https://cdn.bootcss.com/popper.js/1.15.0/umd/popper.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>
模板中的关键语句为{{ login_form }},该位置插入了表单对象。用户填写表单并提交后,view中的login函数通过执行login_form = forms.UserForm(request.POST)获取提交数据,进而进行校验等操作。
结合上述视图与模板,权限管理的基本框架已搭建完成。其核心机制在于将用户输入数据存入Session,并在后续请求中从Session取出数据进行合法性校验。只需在index.html中也加入Session校验逻辑,直接通过URL访问的用户因无Session数据,将被自动拦截。
4. views.index视图逻辑
def index(request):
if not request.session.get('is_login', None): #如果不在登陆状态,就重定向到login
return redirect('/login/')
return render(request, 'login/index.html') #如果在登陆状态,就进入index.html的模板文件
该视图逻辑清晰:若用户未处于登录状态(即session中无is_login或为False),则重定向至login页面;若已登录,则渲染并返回login/index.html模板。在该模板中可开发具体业务功能,demo中的login/index.html内容如下:
<!DOCTYPE html>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
{# 以下三者的引用顺序是固定的#}
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script src="https://cdn.bootcss.com/popper.js/1.15.0/umd/popper.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>
</html>
模板中关键语句为{{ login_form }},此处插入表单对象。用户填写并提交后,view中的login函数通过执行login_form = forms.UserForm(request.POST)获取数据并进行校验。结合视图与模板,权限管理基本完成。其本质机制是将用户数据存入Session,校验时从Session取出判断合法性。只需在index.html中也加入Session校验,直接通过网址访问的用户因无Session,将被拦截。
4. views.index视图逻辑(重复段落,保持原意改写)
def index(request):
if not request.session.get('is_login', None): #如果不在登陆状态,就重定向到login
return redirect('/login/')
return render(request, 'login/index.html') #如果在登陆状态,就进入index.html的模板文件
该视图逻辑清晰:若用户未处于登录状态,则重定向至login页面;若已登录,则渲染并返回login/index.html模板。在该模板中可开发具体业务功能,demo中的login/index.html内容如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>{{ request.session.user_name }}! 欢迎回来!</h1>
<p>
<a href="/logout/">登出</a>
</p>
</body>
</html>

最后,分析logout登出功能的实现。
5. views.logout视图逻辑
def logout(request): #登出
if not request.session.get('is_login', None): #如果不在登陆状态,就直接转发到登陆界面
# 如果本来就未登录,也就没有登出一说
return redirect("/login/")
request.session.flush() #清空session
# 或者使用下面的方法
# del request.session['is_login']
# del request.session['user_id']
# del request.session['user_name']
return redirect("/login/") #重定向到login界面
若用户未登录,直接重定向至/login/界面;若用户已登录,需先调用request.session.flush()清空Session数据,然后再重定向至/login/登录界面。
6. 总结Session与Forms的配合使用
Forms主要在HTML中通过将表单与对象绑定,使得填写表单后能通过Forms轻松获取填写内容。Session则是权限校验的高效工具。未使用Session时,用户可直接访问index界面;使用Session后,index函数的处理逻辑变为通过Session判断登录状态。同时,必须配合login、logout等函数维护Session信息,确保一个不变性:只有当Session中is_login字段为True时,才视为真正登录的用户。
至此,关于Django中Session进行权限管理的使用介绍完毕。更多相关Django Session权限管理内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













