07- django组件:中间件

Posted venicid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了07- django组件:中间件相关的知识,希望对你有一定的参考价值。

1、中间件的概念

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。

 Django的中间件的定义:

Middleware is a framework of hooks into Django’s request/response processing. 
It’s a light, low-level “plugin” system for globally altering Django’s input or output.

如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

 技术分享图片

Django 默认的Middleware

MIDDLEWARE = [
    django.middleware.security.SecurityMiddleware,
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    django.middleware.csrf.CsrfViewMiddleware,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
]

 

 

3、自定义中间件

中间件中一共有四个方法:

技术分享图片
process_request

process_view

process_exception

process_response

 

技术分享图片

技术分享图片技术分享图片

 技术分享图片

 

   (1)添加process_request 请求方法

 

技术分享图片

  (2)添加到settings

技术分享图片

 

 技术分享图片

 

   (3)添加process_response响应方法

技术分享图片

 技术分享图片

 技术分享图片

 

 

  (4)添加中断

 技术分享图片

 技术分享图片

技术分享图片

 

  (5)process_view

process_view(self, request, callback, callback_args, callback_kwargs)

  技术分享图片

 

技术分享图片

技术分享图片

 

技术分享图片

 

 技术分享图片

技术分享图片

  midware1 也添加 视图

技术分享图片

 技术分享图片

 

技术分享图片

 

  去掉 return

 技术分享图片

 技术分享图片

技术分享图片

 

技术分享图片

  执行call_back 函数,实质就是执行 view视图函数

 技术分享图片

技术分享图片

 

  (6)process_exception 异常函数

技术分享图片技术分享图片

当views出现错误时

  技术分享图片

  django自带的报错页面

技术分享图片

 

  自定义这样的views视图错误

 技术分享图片

 捕获顺序

mid1捕获异常,返回页面,mid2 不捕获

技术分享图片

 

技术分享图片

 技术分享图片

技术分享图片

如果 mid1不捕获,mid2捕获

技术分享图片

技术分享图片

技术分享图片

技术分享图片

 

技术分享图片

 

3、完整代码

url

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path(admin/, admin.site.urls),
    re_path(r"^index/$", views.index, name="index")
]

 

view视图

from django.shortcuts import render, HttpResponse

def index(request):
    print("index ......")
    yuna
    return HttpResponse("index页面")

 

 

my_middlewares.py  自定义中间件

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, render   # Httprespnse对象


# 自定义中间件
class MyMiddleware(MiddlewareMixin):   # 继承MiddlewareMixin

    def process_request(self, request):
        print("MyMiddleware 请求...")
        # return HttpResponse("forbidden 禁止")        # 被禁止的

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("MyMiddleware 视图")

        # return HttpResponse("视图 000")

    def process_exception(self, request, exception):
        print("MyMiddleware 异常")
        # return HttpResponse("md1  hello yuan" )

    def process_response(self, request, response):
        print("MyMiddleware 响应!!!")
        return response


class MyMiddleware2(MiddlewareMixin):
    def process_request(self, request):
        print("MyMiddleware222 请求...")

    def process_view(self, request, callback, callback_args, callback_kwargs):
        # print("+++++++>>", callback(callback_args))
        print("MyMiddleware22 视图")
        # ret = callback(callback_args)
        # return ret

    def process_exception(self, request, exception):
        print("MyMiddleware222 异常")
        return HttpResponse("<h1>mid2 %s<h1>" % exception)

    def process_response(self, request, response):
        print("MyMiddleware22 响应!!!")
        return response

 

 

settings中引入自定义中间件

MIDDLEWARE = [
    django.middleware.security.SecurityMiddleware,
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    django.middleware.csrf.CsrfViewMiddleware,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
    app01.my_middlewares.MyMiddleware,
    app01.my_middlewares.MyMiddleware2,
]

 

 

4、中间件应用之用户认证

通过中间件实现装饰器 @login_required  用户认证

(1)用户认证组件实现

url

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path(admin/, admin.site.urls),
    re_path(r"^login/$", views.login, name=login),
    re_path(r"^index/$", views.index, name=index),
    re_path(r"^order/$", views.order, name=order),
    re_path(r"^logout/$", views.logout, name=logout),
    re_path(r"^reg/$", views.reg, name=reg),
]

 

 

views

from django.shortcuts import render, redirect
from django.contrib import auth     # auth认证模块
from django.contrib.auth.decorators import login_required    # 装饰器登录模块
from django.contrib.auth.models import User     # 导入auth_user表对象
# Create your views here.


def login(request):
    if request.method == POST:
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        user = auth.authenticate(username=user, password=pwd)   # 用户认证下
        if user:
            auth.login(request, user)   # request.user == user 当前登录用户对象

            next_url = request.GET.get("next_url", "/index/")
            return redirect(next_url)

    return render(request, "login.html")


@login_required
def index(request):

    return render(request, "index.html")


@login_required
def order(request):

    return render(request, "order.html")


def logout(request):
    auth.logout(request)

    return redirect("/login/")


def reg(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        user_obj = User.objects.create_user(username=user,password=pwd)
        return redirect("/login/")

    return render(request, reg.html)

 

 

settings

# 添加
LOGIN_URL = "/login/"

 

 

注册html

技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h3>注册页面</h3>
<form action="" method="post">
    {% csrf_token %}
    useranme <input type="text" name="user">
    password <input type="text" name="pwd">
    <input type="submit" value="注册">
</form>

</body>
</html>
View Code

 

登录

技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h3>登录页面</h3>
<form action="" method="post">
    {% csrf_token %}
    username <input type="text" name="user">
    password <input type="text" name="pwd">
    <input type="submit" value="登录">
</form>

</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h3>登录页面</h3>
<form action="" method="post">
    {% csrf_token %}
    username <input type="text" name="user">
    password <input type="text" name="pwd">
    <input type="submit" value="登录">
</form>

</body>
</html>
View Code

 

index

技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>index页面</h3>
<h3>hi {{ request.user.username }}</h3>
<a href="/order/">前往order页面</a>
<a href="/logout/">注销</a>
</body>
</html>
View Code

 

order

技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>order 页面</h3>
<h3>hi {{ request.user.username }}</h3>
<a href="/index/">前往index页面</a>

</body>
</html>
View Code

 

 

技术分享图片技术分享图片

 数据迁移

C:PycharmProjectsauthorMid>python manage.py makemigrations
C:PycharmProjectsauthorMid>python manage.py migrate

  技术分享图片

技术分享图片技术分享图片

注销后返回login页面

技术分享图片

没有认证,不能访问index,order

技术分享图片技术分享图片

 

   (2)中间件实现 @login_required

技术分享图片

用户认证中间件my_middlewares

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
from authorMid import settings


class AuthMiddleware(MiddlewareMixin):

    def process_request(self,request):
        white_list = settings.WHITE_LIST
        if request.path in white_list:
            return None
        if not request.user.is_authenticated:
            return redirect("/login/")

 

 

settings添加中间件

MIDDLEWARE = [
    django.middleware.security.SecurityMiddleware,
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    django.middleware.csrf.CsrfViewMiddleware,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
    app01.my_middlewares.AuthMiddleware,
]

LOGIN_URL = "/login/"

# 设置白名单
WHITE_LIST = ["/login/", "/reg/", "/logout/"]

 

 

 

views

技术分享图片
from django.shortcuts import render, redirect, HttpResponse
from django.contrib import auth     # auth认证模块
from django.contrib.auth.decorators import login_required    # 装饰器登录模块
from django.contrib.auth.models import User     # 导入auth_user表对象
# Create your views here.


def login(request):
    if request.method == POST:
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        user = auth.authenticate(username=user, password=pwd)   # 用户认证下
        if user:
            auth.login(request, user)   # request.user == user 当前登录用户对象

            next_url = request.GET.get("next_url", "/index/")
            return redirect(next_url)

    return render(request, "login.html")


# @login_required
def index(request):

    return render(request, "index.html")


# @login_required
def order(request):

    return render(request, "order.html")


def logout(request):
    auth.logout(request)

    return redirect("/login/")


def reg(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        user_obj = User.objects.create_user(username=user,password=pwd)
        return redirect("/login/")

    return render(request, reg.html)
View Code

 

技术分享图片技术分享图片

 

 技术分享图片

 

 

 

 

 

 

5、应用案例

1、做IP访问频率限制

某些IP访问服务器的频率过高,进行拦截,比如限制每分钟不能超过20次。

2、URL访问过滤

如果用户访问的是login视图(放过)

如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!

 

6、源码试读

作为延伸扩展内容,有余力的同学可以尝试着读一下以下两个自带的中间件:

‘django.contrib.sessions.middleware.SessionMiddleware‘,
‘django.contrib.auth.middleware.AuthenticationMiddleware‘,

  

 

以上是关于07- django组件:中间件的主要内容,如果未能解决你的问题,请参考以下文章

Django组件:中间件

Django组件-中间件

Django组件---中间件

20 Django组件之中间件

Django:用户认证组件 & 中间件

JavaScript 片段在 Django 模板中不起作用