当前位置: 首页 > news >正文

【Django】-6- 登录用户身份鉴权

一、🛡️ Django 鉴权 & 登录控制 

Django 自带的鉴权系统(用户身份管理小管家)

 

鉴权系统能干啥?

Django 自带的鉴权系统,就像一个 “用户身份管家” ,帮你管好这些事儿:

功能类比
加密存储用户密码把用户的 “秘密”(密码)锁进保险箱,存的时候自动加密~
登录表单提供 “登录页面模板”(虽然需要自己改改样式,但基础功能有了)~
验证账号密码检查用户输入的账号密码对不对,像 “门卫查身份证”~
验证是否登录判断用户 “有没有带身份凭证”,没登录就不让进某些页面~
针对单用户的权限设置给不同用户发 “权限卡片”(比如管理员能删数据,普通用户只能看)~

 

启用鉴权系统的条件(配置检查)

要让鉴权系统工作,项目里得有这两个 “开关”(在 settings.py ):

① INSTALLED_APPS 里要有这俩
INSTALLED_APPS = [..."django.contrib.auth",  # 鉴权核心功能"django.contrib.contenttypes",  # 辅助管理权限...
]

  • 类比:给 “身份管家” 开通 “系统权限”,让它能在项目里工作~

 

② MIDDLEWARE 里要有这俩中间件
MIDDLEWARE = [..."django.contrib.sessions.middleware.SessionMiddleware",  # 管理用户会话(登录状态)"django.contrib.auth.middleware.AuthenticationMiddleware",  # 管理用户身份验证...
]

  • SessionMiddleware:给用户发 “会话饼干”(记录登录状态)~
  • AuthenticationMiddleware:检查用户的 “身份饼干”,确认是否登录~
  • 类比:给 “身份管家” 配两个小助手,一个发饼干、一个查饼干~

 

禁止匿名访问(拦住没登录的人!)

场景

有些页面 / 功能(比如 “发布评论”),必须 登录后才能用 !如果匿名用户(没登录的人)访问,就 “拦住他”,让他先登录~

 

方法 1:手动判断(一步步拦)

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt  # 演示用,实际要开CSRFdef submit(request):# request.user 是鉴权系统给的“用户身份对象”if not request.user.is_authenticated:  # is_authenticated 是“检查是否登录”的小开关return HttpResponse("请登录后再发布", status=401)# 登录了就继续处理发布逻辑...
流程:
  1. request.user:鉴权系统把 “当前用户身份” 放到 request 里,你可以直接用~
  2. request.user.is_authenticated:判断用户 是否登录 (登录了返回 True ,没登录返回 False )~
  3. 如果没登录,返回 “请登录” 的提示(status=401 表示 “未授权” )~
类比:

你:“小管家!看看这个用户有没有登录,没登录就拦住他!”
小管家:检查 request.user 的 “身份凭证”,没登录就说 “请先登录~”

 

方法 2:@login_required 装饰器(一键拦)

from django.contrib.auth.decorators import login_required@login_required
def submit(request):# 只有登录用户能进这个视图!...
流程:
  • @login_required 是 Django 提供的 “快捷拦人装饰器”~
  • 如果用户没登录,自动 跳转到登录页面 (需要在 settings.py 配置 LOGIN_URL )~
类比:

你给 “发布评论” 的门挂了一个 “登录才能进” 的魔法门牌(@login_required )~
没登录的人想进门,直接被传送到 “登录页面”~

 

方法 2 的配置(让跳转生效)

在 settings.py 里加一行:

LOGIN_URL = '/login/'  # 登录页面的 URL

  • 这样,匿名用户访问被 @login_required 装饰的视图时,会自动跳转到 /login/ ~

 Django 为了方便开发者处理用户的认证(登录、登出等)相关操作,内置了一套鉴权系统。

当你在项目的 URL 配置里,使用 include("django.contrib.auth.urls") 后,就相当于给项目 “接入” 了鉴权系统的一系列 URL (添加一个路由),其中就有 /accounts/login/ 。

它的工作方式

 

视图函数

当用户访问 /accounts/login/ 时,Django 会找到鉴权系统里对应的视图函数( LoginView ,它是一个基于类的视图)。这个视图函数就像一个 “登录小助手”,负责处理用户登录的逻辑,比如验证用户输入的用户名和密码是否正确。

 

表单处理

 LoginView 会自动生成一个登录表单 ,包含用户名和密码的输入框。就好比小助手准备了一张 “登录申请表”,让用户填写信息。而且它还会对用户提交的表单数据进行校验,看看用户名和密码是不是匹配数据库里存储的用户信息。

 

登录状态管理

如果用户输入的信息正确,LoginView 会通过 Django 的会话机制,给用户设置登录状态。这就像给用户发了一张 “小镇通行证”,用户后续访问需要登录才能查看的页面时,Django 就能通过这张 “通行证” 确认用户已经登录啦。

 

可定制性

虽然 /accounts/login/ 是 Django 提供的,但它也是可以定制的哦。默认情况下它会去寻找 registration/login.html 这个模板文件来展示登录页面

总结(小剧场)

鉴权系统小剧场

你:“小管家!我需要管理用户登录、权限,你能帮我吗?”
小管家:“当然!我有加密密码、验证登录、管理权限的本事~ 不过你得在 settings.py 里开一下我的权限!”

 

禁止匿名访问小剧场

方法 1 场景
用户(没登录)想访问 “发布评论” 页面~
小管家检查 request.user ,发现没登录 → 拦住:“请登录后再发布!”

方法 2 场景
用户(没登录)想访问 “发布评论” 页面~
小管家看到门上挂了 @login_required → 直接把用户传送到登录页面:“先登录才能进!”

二、🚪 Django 登录页面实现 

实现登录页面的流程(创建视图 + 路由)

 

1. 核心思路

Django 自带的鉴权系统,已经帮我们写好了 登录逻辑 (验证账号密码、设置登录状态),但 登录页面的模板需要自己提供 !

实现步骤就两步:

  • 配路由(让 /accounts/login/ 能找到 Django 自带的登录视图)
  • 写登录页面模板(告诉 Django 登录页面长啥样)

 

2. 配置路由(让请求找到 Django 登录视图)

from django.urls import path, includeurlpatterns = [# 包含 Django 自带的 auth 路由path("accounts/", include("django.contrib.auth.urls")),
]

  • include("django.contrib.auth.urls"):这是 Django 提供的 “快捷路由”,里面包含了 /accounts/login//accounts/logout/ 等常用登录、登出路由~
  • 类比:你给 “登录功能” 的请求,设置了一个 “自动导航”,让 Django 自带的登录视图处理请求~
访问效果

当你访问 http://127.0.0.1:8000/accounts/login/ 时,Django 会找到自带的 LoginView 处理请求~

 

报错分析:TemplateDoesNotExist(模板找不到)

错误信息解读

TemplateDoesNotExist at /accounts/login/
registration/login.html

  • Django 想找 registration/login.html 这个模板文件,但没找到~

为什么会找这个模板?

Django 自带的 LoginView 默认会去 templates/registration/login.html 找登录页面模板~
如果你的项目里没有这个文件,就会报错!

 

解决方法(给 Django 一个登录页面)

 

方法 1:自己写 login.html 模板

步骤 1:创建模板文件

在你的 App(比如 beifan )目录下,创建这样的路径:

beifan/
└── templates/└── registration/└── login.html

template、registration是目录

  • 路径必须是 templates/registration/login.html ,因为 Django 默认找这个位置~

 

步骤 2:写模板内容

在 login.html 里写登录页面的 HTML ,比如:

<!DOCTYPE html>
<html>
<head><title>登录</title>
</head>
<body><h1>欢迎登录</h1><form method="post">{% csrf_token %}  <!-- 必须加,防止跨站攻击 -->{{ form.as_p }}   <!-- 自动渲染登录表单 --><button type="submit">登录</button></form>
</body>
</html>

  • {{ form.as_p }}:Django 会自动生成用户名、密码的输入框~

 

方法 2:复用 Django admin 的登录模板(偷懒版)

错误信息里的提示
{# beifan/templates/registration/login.html #}
{% extends "admin/login.html" %}

  • 这行代码的意思是:“让登录页面继承 Django admin 的登录模板”,这样不用自己写样式~

 

步骤 1:创建模板文件

同样在 beifan/templates/registration/login.html 里写:

{% extends "admin/login.html" %}

  • {% extends "admin/login.html" %}:表示 “我的登录页面,用 Django admin 的登录页面样式”~

 

步骤 2:确保 Django 能找到模板

在 settings.py 里,确保你的 App(beifan )在 INSTALLED_APPS 里,并且模板配置正确:

INSTALLED_APPS = [...'beifan',...
]TEMPLATES = [{...'APP_DIRS': True,  # 允许 Django 在 App 的 templates 目录找模板...},
]

 

步骤 3:检查模板路径

确保你的模板文件路径是:

beifan/
└── templates/└── registration/└── login.html

  • 这样 Django 就能找到 registration/login.html ,继承 admin/login.html 的样式~

 

总结(小剧场)

实现登录页小剧场

你:“Django 呀,我要做个登录页面,用户访问 /accounts/login/ 时能登录~”
Django:“好呀!你配好路由(include('django.contrib.auth.urls') ),再给我一个 registration/login.html 模板,我就能显示登录页面啦!”

报错解决小剧场

你访问 /accounts/login/ ,Django 大喊:“找不到 registration/login.html 模板!”
你:“哦~ 原来要自己创建这个文件!”
于是你在 beifan/templates/registration/ 里创建 login.html ,要么自己写内容,要么继承 admin/login.html ,问题解决!

三、🎨 什么是Django 模板 

模板就是 “HTML 半成品 + Django 魔法标记” ,让你能把 Python 数据(比如模型数据、变量)动态渲染到网页里~ 

模板是干啥的?

想象你要做 100 个 “用户订单详情页”,每个页面的结构一样(比如标题、表格),但数据不同(订单号、商品、价格)。

  • 如果纯手写 HTML ,得复制 100 个文件,改数据 → 超麻烦!
  • 用 Django 模板 → 写一个 “模板文件”(HTML 框架 + 动态标记),然后传不同数据进去,自动生成 100 个页面!

 

模板长啥样?(结构拆解)

1. 普通 HTML 部分(静态内容)
<!DOCTYPE html>
<html>
<head><title>我的页面</title>
</head>
<body><h1>欢迎来到我的网站!</h1><p>这是一段固定不变的文字~</p>
</body>
</html>

  • 这部分和普通 HTML 一样,是静态内容(所有用户看到的都一样)~

 

2. Django 魔法标记(动态内容)
<!DOCTYPE html>
<html>
<head><title>{{ page_title }}</title>  <!-- 动态标题 -->
</head>
<body><h1>欢迎 {{ user_name }} 来到我的网站!</h1>  <!-- 动态用户名 --><p>你的订单号是:{{ order.id }}</p>  <!-- 动态订单号 -->{% if user.is_vip %}  <!-- 条件判断 --><p>你是 VIP 用户,享受专属优惠~</p>{% endif %}{% for product in products %}  <!-- 循环遍历 --><li>{{ product.name }} - 价格:{{ product.price }}</li>{% endfor %}
</body>
</html>

  • {{ 变量 }}插入 Python 变量(比如 page_titleuser_name ),把后端数据动态渲染到 HTML 里~
    类比:在 HTML 里 “挖个坑”,让后端传数据填进来~

  • {% 标签 %}控制逻辑(比如 if 判断、for 循环 ),让 HTML 能根据后端数据 “动态变化”~
    类比:给 HTML 加 “魔法指令”,让它能判断、循环,变聪明~

 

模板的作用(为啥需要它?)

1. 分离前后端
  • 后端(Python)负责 “处理数据、业务逻辑”,前端(HTML)负责 “页面展示”~
  • 模板就是 “桥梁”:让后端把数据传给前端,前端用 HTML + 魔法标记展示数据~
2. 复用代码
  • 一个模板可以渲染 N 个页面(传不同数据就行),不用重复写 HTML 结构~
3. 动态交互
  • 结合 {{ }} 和 {% %} ,让页面能根据用户、数据的不同,展示不同内容~

 

模板的使用流程(小剧场)

1. 后端准备数据

from django.shortcuts import renderdef my_view(request):# 准备要传给模板的数据(字典形式)context = {'page_title': '我的动态页面','user_name': '北凡','order': {'id': 123},'user': {'is_vip': True},'products': [{'name': '魔法棒', 'price': 99},{'name': '仙女裙', 'price': 199},]}# 渲染模板,把 data 传给模板return render(request, 'my_template.html', context)

 

2. 前端模板 my_template.html 接收数据

<!DOCTYPE html>
<html>
<head><title>{{ page_title }}</title>
</head>
<body><h1>欢迎 {{ user_name }} 来到我的网站!</h1><p>你的订单号是:{{ order.id }}</p>{% if user.is_vip %}<p>你是 VIP 用户,享受专属优惠~</p>{% endif %}<h3>你的商品:</h3><ul>{% for product in products %}<li>{{ product.name }} - 价格:{{ product.price }}</li>{% endfor %}</ul>
</body>
</html>

 

3. 最终渲染的 HTML(用户看到的)

<!DOCTYPE html>
<html>
<head><title>我的动态页面</title>
</head>
<body><h1>欢迎 北凡 来到我的网站!</h1><p>你的订单号是:123</p><p>你是 VIP 用户,享受专属优惠~</p><h3>你的商品:</h3><ul><li>魔法棒 - 价格:99</li><li>仙女裙 - 价格:199</li></ul>
</body>
</html>

 

模板的存放位置

Django 会在这些地方找模板:

  1. 项目根目录的 templates 文件夹(适合全局模板)
  2. 每个 App 目录下的 templates 文件夹(适合 App 专属模板)

比如你的 App 叫 beifan ,模板可以放在:

beifan/
└── templates/└── beifan/└── my_template.html

 

总结

模板就是 “会魔法的 HTML” ,通过 {{ }} 插变量、{% %} 写逻辑,让后端数据能动态渲染到前端页面里~

它让前后端分离更清晰、代码复用更方便、页面交互更灵活~ 掌握模板,就能做出 “千人千面” 的动态网页啦! 🎉

 

http://www.lryc.cn/news/608456.html

相关文章:

  • Mybatis学习之获取参数值(四)
  • 第14届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2023年1月15日真题
  • STM32学习记录--Day6
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘seaborn’问题
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现道路车辆事故的检测识别(C#代码UI界面版)
  • SpringBoot 服务器配置
  • 面经——电子电路技术知识详解
  • 【Python3教程】Python3高级篇之网络编程
  • 文心4.5开源测评:国产大模型的轻量化革命与全栈突破
  • GaussDB 约束的使用举例
  • 高效轻量的C++ HTTP服务:cpp-httplib使用指南
  • Redis核心机制与实践深度解析:从持久化到分布式锁
  • 路面障碍物识别漏检率↓76%:陌讯多模态融合算法实战解析
  • 基于 LFU 策略的存储缓存系统设计与实现
  • 人工智能之数学基础:离散型随机事件概率(古典概型)
  • 兰空图床部署教程
  • LQR个人笔记
  • Unity_数据持久化_C#处理XML文件
  • ollama 多实例部署
  • 睡岗识别误报率↓76%:陌讯动态时序融合算法实战解析
  • JP3-3-MyClub后台后端(三)
  • 小迪23-28~31-js简单回顾
  • 解决mac在安装nvm过程中可能遇到的一些问题
  • 小迪23年-22~27——php简单回顾(2)
  • (nice!!!)(LeetCode 每日一题) 2561. 重排水果 (哈希表 + 贪心)
  • 【自动化运维神器Ansible】YAML支持的数据类型详解:构建高效Playbook的基石
  • 译| Netflix内容推荐模型的一些改进方向
  • Tlias案例-登录 退出 打包部署
  • Leetcode 11 java
  • 论文笔记:Bundle Recommendation and Generation with Graph Neural Networks