Django Session权限管理实战:登录、校验与登出全流程解析

小林子
小林子
发布时间:2026-10-14| 3人浏览过
原创

本文详细解析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权限管理内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。