zoukankan      html  css  js  c++  java
  • 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',
    

      

  • 相关阅读:
    centos 给终端设快捷键
    centos 给鼠标右击添加 “打开终端” 菜单项
    centos 6.X 安装输入法
    centos U盘安装
    js的构造函数
    onresize的定义方式
    两个时间对比
    AMD和CMD的区别
    spring加载配置文件
    cglib代理
  • 原文地址:https://www.cnblogs.com/venicid/p/9320482.html
Copyright © 2011-2022 走看看