Django — 类视图和中间件

news2024/11/25 2:34:13

目录

  • 一、类视图
    • 1、基于类的结构
    • 2、常见的类视图基类
    • 3、类视图的优点
    • 4、代码案例
  • 二、中间件
    • 1、定义
    • 2、工作原理
    • 3、自带中间件
    • 4、中间件开发流程
    • 5、自定义中间件
    • 6、案例

一、类视图

类视图(Class-Based Views)是 Django 中用于处理 HTTP 请求和生成 HTTP 响应的一种方式,它们基于 Python 类来定义视图逻辑。

相对于基于函数的视图,类视图提供了更结构化、可维护和可扩展的方式来编写 Web 应用程序的视图逻辑。

1、基于类的结构

类视图是 Python 类,通常继承自 Django 的通用视图类,如 View 、TemplateView、ListView、DetailView 等。每个类视图通常包括一个或多个方法,每个方法对应于不同的HTTP请求方法(如 GET、POST 等)。

2、常见的类视图基类

Django 提供了一些常见的类视图基类,它们可以用作基础类,以便快速创建常见的视图。以下是一些常见的类视图基类:

  • View:最基本的类视图,可以从这个基类派生并定义 get()、post() 等方法来处理不同的 HTTP 请求。
  • TemplateView:用于渲染模板的类视图,通常用于显示静态内容的页面。
  • ListView:用于显示对象列表的类视图,自动处理分页和对象检索。
  • DetailView:用于显示单个对象的详细信息的类视图。
  • CreateView、UpdateView、DeleteView:用于创建、更新和删除对象的类视图,自动处理表单验证和重定向。
  • RedirectView:用于重定向用户到其他URL的类视图。

3、类视图的优点

  • 可维护性和可读性:类视图允许将相关的视图逻辑组织成一个类,使代码更具可读性和可维护性。每个 HTTP 请求方法通常对应于类中的一个方法,例如 get()、post() 等。
  • 代码重用:可以轻松地创建基础类视图,并在多个视图中继承它们,从而实现视图逻辑的重用。这有助于减少重复编码,提高代码的效率。
  • 扩展性:类视图支持继承,可以构建具有继承关系的视图。就是可以在基础视图上添加或覆盖方法,以实现不同的行为。
  • 可测试性:由于视图逻辑更模块化,因此更容易编写单元测试来验证视图的行为。

4、代码案例

# Project 项目中的 urls.py
from django.urls import path,include  # 导入 Django 的 path 函数,用于配置 URL 路由,include 函数,用于将其它 URL 模式包含在当前 URL 配置中

# URL 配置列表,定义了网站的所有 URL 路径和对应的处理程序
urlpatterns = [
    # 配置 URL 路由
    path('', include('users.urls'))
]
# users 子应用的 urls.py
from django.urls import path  # 导入 Django 的 path 函数,用于配置 URL 路由
from .import views  # 导入当前目录下的 views.py 文件中的模块或视图函数

# URL 配置列表,定义 URL 路径和对应的处理程序
urlpatterns = [
    # 使用 path 函数将'/register/'路径映射到 RegisterView 类视图
    path('register/',views.RegisterView.as_view()),
]
# 子应用的 views.py
from django.views import View  # 导入 View 类,用于创建类视图
from django.shortcuts import render  # 导入 render 函数,用于渲染模板
from django.http import HttpResponse  # 导入 HttpResponse 类,用于创建 HTTP 响应

class RegisterView(View):
    # 处理 GET 请求,显示用户注册页面
    def get(self, request):
        # 使用 render 函数渲染并返回 register.html 模板
        return render(request, 'register.html')

    # 处理 POST 请求,接收并处理用户提交的注册信息
    def post(self, request):
        # 打印 request 对象,可选,用于调试和查看请求信息
        print(request)
        # 从 POST 请求中获取用户提交的用户名和密码
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 打印用户名和密码,可选,用于调试和查看用户提交的数据
        print(username)
        print(password)
        # 在这里处理用户提交的注册信息,例如将信息保存到数据库
        # 返回一个简单的HTTP响应,表示注册成功
        return HttpResponse('注册成功')

在根目录下创建 templates 文件夹。

# setting.py
# 设置模板引擎配置,包括模板目录、模板上下文处理器等。
TEMPLATES = [
    {
        # Django 模板引擎的配置项
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 额外的模板目录,留空表示使用默认的模板目录
        'DIRS': [BASE_DIR / 'templates'],
        # 表示启用应用程序模板目录
        'APP_DIRS': True,
        # Django 模板引擎配置的一部分,用于指定模板上下文处理器(context processors)的选项
        'OPTIONS': {
            # 一个列表,用于指定要应用的模板上下文处理器。
            'context_processors': [
                # Django 自带的模板上下文处理器
                'django.template.context_processors.debug',
                # Django 自带的模板上下文处理器
                'django.template.context_processors.request',
                # Django 自带的模板上下文处理器
                'django.contrib.auth.context_processors.auth',
                # Django 自带的模板上下文处理器
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

在 templates 文件夹下,新建 register.html 文件并编写。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="#" method="post">
        username: <input  type="text" id="username" name="username"><br>
        password: <input type="password" id="password" name="password" ><br>
        register: <button type="submit">注册</button>
    </form>
</body>
</html>

二、中间件

1、定义

用于在请求和响应处理过程中执行预定义的操作。

中间件可以在 HTTP 请求到达视图之前和响应返回给客户端之前执行各种任务,例如身份验证、日志记录、性能优化、安全性检查等。

在这里插入图片描述

2、工作原理

请求阶段

  • 当用户发送 HTTP 请求时,Django 中间件首先介入。
  • 请求在到达视图之前,通过一系列中间件按顺序处理。
  • 每个中间件都可以选择处理请求、修改请求、记录信息或执行其他操作。

视图处理

  • 请求最终到达视图函数,视图函数处理请求并生成一个 HTTP 响应。

响应阶段

  • 响应在返回给客户端之前,通过一系列中间件按相反的顺序处理。
  • 每个中间件都可以选择处理响应、修改响应、记录信息或执行其他操作。

请求是从上往下,响应是从下往上。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、自带中间件

  • SecurityMiddleware(django.middleware.security.SecurityMiddleware):
    • 功能:提供基本的安全性功能。
    • 作用:例如,设置点击劫持保护、X-Content-Type-Options 头部等。
    • 用途:增加 Web 应用程序的安全性。
  • SessionMiddleware(django.contrib.sessions.middleware.SessionMiddleware):
    • 功能:处理会话数据。
    • 作用:存储和管理用户的会话信息。
    • 用途:用于跟踪用户会话状态,允许在不同请求之间共享数据。
  • CommonMiddleware(django.middleware.common.CommonMiddleware):
    • 功能:提供一些常见的 HTTP 处理功能。
    • 作用:例如,URL 规范化、缓存控制、Content-Type 头部处理等。
    • 用途:用于执行一些通用的 HTTP 操作,以确保 Web 应用程序的正常运行。
  • CsrfViewMiddleware(django.middleware.csrf.CsrfViewMiddleware):
    • 功能:用于防止跨站请求伪造(CSRF)攻击。
    • 作用:生成和验证 CSRF 令牌,确保 POST 请求的来源合法。
    • 用途:提供安全性保护,确保用户提交的表单是合法的。
  • AuthenticationMiddleware(django.contrib.auth.middleware.AuthenticationMiddleware):
    • 功能:在每个请求中更新用户的身份信息。
    • 作用:根据会话中的用户信息识别用户,并将 request.user 设置为当前用户对象。
    • 用途:管理用户身份验证状态,允许用户登录和注销。
  • MessageMiddleware(django.contrib.messages.middleware.MessageMiddleware):
    • 功能:在请求和响应之间传递消息。
    • 作用:支持在一次请求中显示一次性消息,例如成功消息或错误消息。
    • 用途:用于向用户呈现提示、通知和消息。
  • XFrameOptionsMiddleware(django.middleware.clickjacking.XFrameOptionsMiddleware):
    • 功能:设置 HTTP 响应的 X-Frame-Options 头部,以控制页面的嵌套(防止点击劫持攻击)。
    • 作用:增加网页的安全性,防止在 iframe 中嵌套网页。
    • 用途:保护网页免受点击劫持攻击。

4、中间件开发流程

  • 在项目中创建一个用于存放中间件代码的文件夹。
  • 在此文件夹中进行中间件的设计。
  • 中间设计好了之后,需要将自定义的中间件注册到项目之中。

5、自定义中间件

1、在子应用中创建自定义中间件文件 middlewarse.py。

# users 子应用的 middlewarse.py
from django.http import HttpResponse  # 导入 HttpResponse 类,用于创建自定义 HTTP 响应对象
from django.utils.deprecation import MiddlewareMixin  # 导入 MiddlewareMixin 类,它是编写中间件的基类,用于方便地定义中间件类

# 定义中间件类 MD1,继承自 MiddlewareMixin
class MD1(MiddlewareMixin):
    # 在请求处理之前执行的方法
    def process_request(self, request):
        print("md1  process_request 方法", id(request))

    # 在响应返回客户端之前执行的方法
    def process_response(self, request, response):
        print("md1  process_response 方法", id(request))
        # 返回响应对象,可以对响应进行修改或不做修改
        return response

    # 在视图函数被调用之前执行的方法
    def process_view(self, request, view_func, view_args, view_kwargs):
        print("md1  process_view 方法")
        # 调用视图函数并传递请求对象
        return view_func(request)

    # 在视图函数抛出异常时执行的方法
    def process_exception(self, request, exception):
        print("md1  process_exception 方法")
        # 返回一个带有异常信息的 HTTP 响应对象
        return HttpResponse(exception)

# 定义中间件类 MD2,继承自 MiddlewareMixin
class MD2(MiddlewareMixin):
    # 在请求处理之前执行的方法
    def process_request(self, request):
        print("md2  process_request 方法", id(request))

    # 在响应返回客户端之前执行的方法
    def process_response(self, request, response):
        print("md2  process_response 方法", id(request))
        # 返回响应对象,可以对响应进行修改或不做修改
        return response

    # 在视图函数被调用之前执行的方法
    def process_view(self, request, view_func, view_args, view_kwargs):
        print("md2  process_view 方法")
        # 调用视图函数并传递请求对象
        return view_func(request)

    # 在视图函数抛出异常时执行的方法
    def process_exception(self, request, exception):
        print("md2  process_exception 方法")
        # 返回一个带有异常信息的 HTTP 响应对象
        return HttpResponse(exception)
    
# 运行结果:
# md1  process_request 方法 140083017419800
# md2  process_request 方法 140083017419800
# md2  process_response 方法 140083017419800
# md1  process_response 方法 140083017419800

2、在 settings.py 中的中间件的位置加入以下代码。

# settings.py
# 中间件
MIDDLEWARE = [
    # 导入自定义的中间件类
    'users.middlewarse.MD1',  
    'users.middlewarse.MD2',
]

6、案例

做 IP 访问频率限制

# users 子应用的 middlewarse.py
import time  # 导入 time 模块,用于计算时间间隔、获取当前时间等操作
from django.utils.deprecation import MiddlewareMixin  # 导入 MiddlewareMixin 类,它是编写中间件的基类,用于方便地定义中间件类
from django.http import HttpResponse  # 导入 HttpResponse 类,用于创建自定义 HTTP 响应对象

# 创建一些变量和设置
white = ['127.0.0.1']   # 白名单
black = ['127.0.0.2']   # 黑名单
ban = {}                # 小黑屋
ban_seconds = 3         # 三秒内
ban_limit = 5           # 三秒内允许访问5次
ban_time = 30           # 被封时间30秒

# 定义中间件类 AuthMD,继承自 MiddlewareMixin
class AuthMD(MiddlewareMixin):
    # 在每个请求处理之前执行的方法
    def process_request(self, request):
        ip = str(request.META.get("REMOTE_ADDR"))  # 获取请求的 IP 地址
        if ip in black:
            return HttpResponse('禁止访问', status=403)  # 如果 IP 在黑名单中,返回 403 状态码
        # 如果是第一次请求
        if not ban.get(ip):
            ban[ip] = {"total": 1, "time": int(time.time()), "banTime": ""}  # 如果 IP 不在小黑屋中,初始化相关信息
        print(ip, ban[ip].get("total"))  # 打印 IP 和访问次数
        # 如果不是第一次请求,则判断上次请求和这次请求是否在合法时间内
        if ban[ip]["time"] + ban_seconds > int(time.time()):
            # 如果是三秒内,判断访问次数
            if ban[ip]["total"] > ban_limit:
                ban[ip]["banTime"] = int(time.time()) + ban_time  # 如果在封禁时间内访问次数超过限制,设置封禁时间
                return self.ban_response()  # 返回封禁响应
            ban[ip]["total"] += 1  # 如果没有大于限制次数
            print(ban)  # 增加访问次数,并打印小黑屋信息
        # 如果不是在合法时间内请求
        else:
            limit_time = ban[ip]["banTime"]  # 先根据此 IP 找封的时间
            if limit_time and limit_time > int(time.time()):
                return self.ban_response()  # 如果在封禁时间内,返回封禁响应
            del ban[ip]  # 否则从小黑屋中移除 IP 地址

    # 定义封禁响应方法
    def ban_response(self):
        return HttpResponse(f"访问过于频繁,请{ban_time}秒后重试!")

    # 在每个响应返回客户端之前执行的方法
    def process_response(self, request, response):
        return response  # 返回原始响应对象,不做修改
# settings.py
# 中间件
MIDDLEWARE = [
    # 导入自定义的中间件类
    'users.middlewarse.AuthMD',
]

记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1043166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

24届近3年河海大学自动化考研院校

⚜️所谓又专又精&#xff0c;专是指我们售后群团队上百人都是自动化研究生&#xff0c;精是指我们只做自动化这一门专业学科7年了&#xff0c;研究到极致&#xff01; &#x1f509;今天学长给大家带来的是河海大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 目录…

XC9700 单通道限流电流负载开关 低内阻负载开关

XC9700是一种低成本、低电压、单P-MOSFET负载开关&#xff0c;为自供电和总线供电的通用串行总线&#xff08;USB&#xff09;应用进行了优化。该开关的输入范围从2.4V到5.5V&#xff0c;使它非常适合3V和5V系统。该开关的低RDS&#xff08;ON&#xff09;&#xff0c;80mΩ&am…

怒刷LeetCode的第16天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;迭代 方法二&#xff1a;模拟 方法三&#xff1a;循环模拟 方法四&#xff1a;传递 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;回溯 方法二&#xff1a;枚举优化 第三题 题目来源 题目…

Unity之NetCode多人网络游戏联机对战教程(3)--NetworkObject组件讲解

文章目录 NetworkObjectAlways Replicate As RootSynchronization TransformActive Scene SynchronizationScene Migration SynchronizationSpawn With ObserversDont Destroy With OwnerAuto Object Parent Sync 后话 NetworkObject 为了复制任何Netcode感知属性或发送/接收R…

Linux生产者和消费者模型 条件变量 信号量

/*条件变量类型 pthread_cond_tint pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);int pthread_cond_destory(pthread_cond_t * cond);int pthread_cond_wait(pthread_cond_t *restrict cond, const pthread_mutex_t *restrict …

人生第一个java项目 学生管理系统

开始编程 建类 开始主要部分 main()部分 方法部分

Nodejs+vue高校机房设备管理系统jt07u

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 集成IDE对高校机房设备管理系统统进行开发,整合系统的各个模块。 拟开发的高校机房设备管理系统通过测试,确保在最大负载的情况下…

新型crypt勒索病毒,都有哪些特征?勒索病毒解密,数据恢复

近日&#xff0c;云天数据恢复中心在接受用户咨询的过程中发现&#xff0c;市场上悄然出现了一种新型的勒索病毒——crypt勒索病毒&#xff0c;接下来我们将这种类型的勒索病毒做一个全面的分析。 一&#xff0c;中了crypt勒索病毒的特征 在桌面以及多个文件夹中都有一个名称为…

matlab产生指定功率的噪声信号、固定SNR的信号

randn函数产生噪声信号 首先要理解信号的幅度和功率&#xff0c;例如信号的幅度为 U U U&#xff0c;那么信号的功率就是 U 2 U^2 U2&#xff0c;他们之间是平方的关系。 matlab中randn函数用法&#xff0c;产生正态分布的随机数或矩阵的函数。 randn&#xff1a;产生均值为0…

基于Java+vue开发的企事业移动培训考试平台

随着移动互联网的快速发展&#xff0c;越来越多的企业开始关注移动培训和考试平台的开发。为了满足这一需求&#xff0c;我们可以使用Java和Vue来开发一个基于移动端的企事业培训考试平台。 一、背景和需求 企事业移动培训考试平台是一个基于Web的应用程序&#xff0c;旨在提…

el-upload上传文件(vue2,Element中的 el-upload文件上传)

简介&#xff1a;el-upload是一个基于Element UI的上传组件&#xff0c;大家应该都知道&#xff0c;它可以方便地实现文件上传功能&#xff0c;今天来记录下如何&#xff08;在vue2中&#xff09;使用el-upload上传文件。 1、首先&#xff0c;我们想要使用el-upload&#xff0c…

Redux Toolkit中action派发但state值不更新的原因

最近一个react项目使用了Redux Toolkit&#xff0c;但是遇到了一个问题&#xff1a;数组始终返回为null&#xff0c;读取不到length. 这个只是问题的表象&#xff0c;真正的原因是productList数据没能从redux中结构出来 但是postman请求是由数据返回的&#xff1a; 推断&#x…

openMVS编译

参考官方文档&#xff1a;https://github.com/cdcseacave/openMVS/wiki/Building vcglib的安装 cd /home/juling/lib git clone -b v1.0.1 https://github.com/cdcseacave/VCG.git vcglibgit clone --recurse-submodules https://github.com/cdcseacave/openMVS.git cd openMV…

git代码管理(一)

目录 介绍暂存区安装创建仓库提交文件查看当前是否还有文件未提交查看提交历史版本回退恢复版本回退 介绍 git是一个分布式的代码版本管理工具&#xff08;区别于集中式管理的svn&#xff09;&#xff0c;分布式的意思是对于同一个项目可以有多个仓库存储&#xff0c;分布在不…

服务器(Windows系统)自建filebrowser网盘服务器超详细教程

需要依赖&#xff08;工具&#xff09; 轻量服务器&#xff08;云服务器&#xff09;一台 —— 环境Windows Server 2019filebrowser安装包&#xff08;https://github.com/filebrowser/filebrowser/releases&#xff09; 下载安装filebrowser 进入链接下载&#xff1a;https:/…

基于OpenSceneGraph的三维模型格式转换(以OBJ为例),并简化、输出纹理图片到指定目录(附完整C++代码和exe)

文章目录 前言一、OpenSceneGraph库1. OSG源码2. 编译教程2. Windows编译完成版 二、osgconv格式转换工具1. osgconv官方说明文档2. osgconv工具调用 三、基于C格式转换&#xff0c;简化OBJ&#xff0c;输出纹理到指定目录1. 项目环境2. 完整代码3. 可执行文件 前言 本文基于O…

记录:移动设备软件开发(Activity的显式启动和隐式启动)

目录 Intent对象简述Intent的作用Intent开启Activtiy显式启动Activity隐式启动Activity Intent对象简述 Android的应用程序包含三种重要组件&#xff1a;Activity、Service、BroadcastReceiver&#xff0c;应用程序采用了一致的方式来启动它们——都是依靠Intent来启动的&…

flv怎么转换成mp4格式?准备3个方法给大家

flv怎么转换成mp4格式&#xff1f;FLV是一种流行的视频文件格式&#xff0c;最初由Adobe公司开发&#xff0c;用于在Web上播放和传输视频内容。FLV格式以其较小的文件大小和较高的压缩比而闻名&#xff0c;并广泛应用于在线视频分享平台、流媒体服务和网络广告等领域。能够提供…

c++图像的边缘检测

图像的边缘检测 cv::Canny 是 OpenCV 中用于进行边缘检测的函数&#xff0c;特别是用于检测图像中的边缘。Canny 边缘检测是一种广泛使用的技术&#xff0c;它能够识别图像中的边缘&#xff0c;这些边缘通常表示对象之间的边界或图像中的显著特征 void cv::Canny(const cv::M…

linux 查看CPU架构是AMD还是ARM

要查看 Linux 系统的 CPU 架构是 AMD 还是 ARM&#xff0c;可以使用以下命令&#xff1a; 使用 lscpu 命令并查找 Architecture 字段&#xff1a; lscpu | grep Architecture如果输出结果中包含 x86_64 或 i686&#xff0c;则表示系统的 CPU 架构是 AMD&#xff08;或者是 x86…