精华内容
下载资源
问答
  • 自定义 Django 中间件

    2020-05-12 17:48:47
    自定义Django中间件的方式Django 自定义中间件工厂函数类子类注册中间件测试中间件方法的调用时机中间件的执行顺序参考 Django 自定义中间件 Django 中间件是一个轻量级、底层的插件系统,可以介入 Django 的请求和...

    Django 自定义中间件

    Django 中间件是一个轻量级、底层的插件系统,可以介入 Django 的请求和响应处理过程,修改 Django 的输入或输出。
    定义 Django 中间有以下几种方式:

    1. 定义中间件工厂函数
    2. 定义中间件类
    3. 定义中间件子类, 继承自 MiddlewareMixin

    工厂函数

    def simple_middleware(get_response):
        print('第一次配置和初始化的时候执行一次')
    
        def inner(request):
            print('每个请求处理视图前被执行')
    
            response = get_response(request)
    
            print('每个请求处理视图之后被执行')
    
            return response
    
        return inner
    
    

    class MyMid:
    
        def __init__(self, get_response):
            self.get_response = get_response
            
            print('first init')
    
        def __call__(self, *args, **kwargs):
        
            print('MyMid: process request')
            
            response = self.get_response(*args, **kwargs)
            
            print('MyMid: process response')
            
            return response
    
    

    子类

    子类可实现的方法:

    1. process_request
    2. process_view
    3. process_response
    4. process_template_response
    5. process_exception

    继承自 MiddlewareMixin, 不必写 __call____init__ 方法。

    from django.http import HttpResponse
    from django.utils.deprecation import MiddlewareMixin
    
    
    class MyMiddleware(MiddlewareMixin):
    
        def process_request(self, request):
            """Request 预处理方法.
            
            Return: 
                None --> 交给下一个中间件继续处理
                HttpResponse() --> 不再执行任何其它的中间件以及相应的 view,  立即返回该 HttpResponse
            """
            print(request.path)
            print('process_request')
    
        def process_view(self, request, callback, callback_args, callback_kwargs):
            """View 预处理方法.
            Return: 
                None --> Django 将继续处理这个 request, 执行后续的中间件, 然后调用相应的 view
                HttpResponse() --> Django 将不再执行任何其它的中间件以及相应的 view, 立即返回
            """
            print('process_view')
            return None
            # return response
    
        def process_response(self, request, response):
            """Response 后处理方法.
            Return: 
                必须返回 HttpResponse 对象. 
                可以新生成一个 HttpResponse 对象来返回
            """
            print('process_response')
            return response
    
        def process_template_response(self, request, response):
            """在模板渲染前执行.
            Return: 
                返回实现了 render 方法的响应对象
            """
            print('process_template_response')
            return response
    
        def process_exception(self, request, exception):
            """Exception 后处理方法.
            Return: 
                None --> Django 将用框架内置的异常处理机制继续处理相应 request
                HttpResponse() --> Django 将使用该 response,而短路框架内置的异常处理机制
            """
            print('process_exception')
            print('log: ', exception)
            return HttpResponse('Emm, Error!')
    
    

    注册中间件

    """settings.py"""
    
    MIDDLEWARE = [
        # ...
        
        # 根据实际情况修改路径
        'middlewares.mid_test1.MyMiddleware',
        'middlewares.mid_test2.MyMid',
        'middlewares.mid_test3.simple_middleware',
    ]
    
    

    测试中间件方法的调用时机

    创建一个 demo 项目, 然后创建一个 app1 应用, 写好主路由和子路由, 建好模板文件, 定义以下视图。

    # demo/app1/views.py
    from django.http import HttpResponse
    from django.template.response import TemplateResponse
    
    
    def index(request):
        """
        访问视图对应路由时, 类中间件方法的打印顺序:
            process_request
            process_view
            process_response
        """
        return HttpResponse('Hello index.')
    
    
    def exc(request):
        """
        访问视图对应路由时, 类中间件方法的打印顺序:
            process_request
            process_view
            process_exception
            process_response
        """
        raise
    
    
    def template(request):
        """
        访问视图对应路由时, 类中间件方法的打印顺序:
            process_request
            process_view
            process_template_response
            process_response
        """
        # 注: 返回 render 结果时不会走类中间件的 process_template_response,
        # 要测试它, 需要返回 TemplateResponse()
        # return render(
        #     request,
        #     'app1/test.html',
        #     context={'data': 'Hello template.'}
        # )
        return TemplateResponse(
            request,
            'app1/test.html',  # 去找 demo/app1/templates/app1/test.html
            context={'data': 'Hello template.'}
        )
    

    中间件的执行顺序

    多个中间件的执行顺序

    • 在请求视图被处理前,中间件由上至下依次执行
    • 在请求视图被处理后,中间件由下至上依次执行

    参考

    展开全文
  • 自定义django中间件

    2018-05-06 22:04:00
    自定义中间件 第一步:在根目录创建路径Middle/m1.py(注意如果是python2的话Middle下要有__init__.py文件,不然会报找不到模块错误) m1.py的内容: 1 # -*- coding: utf-8 -*- 2 from django.utils....

    自定义中间件

    第一步:在根目录创建路径Middle/m1.py(注意如果是python2的话Middle下要有__init__.py文件,不然会报找不到模块错误)
    m1.py的内容:
     1 # -*- coding: utf-8 -*-
     2 from django.utils.deprecation import MiddlewareMixin
     3 from django.shortcuts import HttpResponse
     4 
     5 class Row1(MiddlewareMixin):
     6     def process_request(self,request):
     7         print ('第一步')
     8 
     9     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
    10         print('中间第一步')
    11 
    12     def process_response(self,request,response):
    13         print ('倒数第一步')
    14         return  response
    15 
    16 class Row2(MiddlewareMixin):
    17     def process_request(self,request):
    18         print ('第2步')
    19 
    20     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
    21         print('中间第2步')
    22 
    23     def process_response(self,request,response):
    24         print ('倒数第2步')
    25         return  response
    26 
    27 class Row3(MiddlewareMixin):
    28     def process_request(self,request):
    29         print ('第3步')
    30 
    31     def process_view(self, request, view_func, view_func_args, view_func_kwargs):
    32         print('中间第3步')
    33 
    34     def process_response(self,request,response):
    35         print ('倒数第3步')
    36         return  response
    37 
    38     def process_exception(self, request, exception):
    39         if isinstance(exception,ValueError):
    40             return HttpResponse('出现异常》。。')
    41 
    42     def process_template_response(self,request,response):
    43         # 如果Views中的函数返回的对象中,具有render方法
    44         print('-----------------------')
    45         return response
    View Code
    项目setting.py中间件的内容:
    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',
        'Middle.m1.Row1',
        'Middle.m1.Row2',
        'Middle.m1.Row3',
    ]
    View Code

    实际输出结果:

    第一步
    第2步
    倒数第2步
    倒数第一步
    View Code

    中间件的作用流程

     

    实际的请求流程图:

     

     

     

    转载于:https://www.cnblogs.com/qiangayz/p/8999967.html

    展开全文
  • 自定义django中间件实现登录

    千次阅读 2018-06-30 13:50:41
    title: 自定义django中间件实现登录 date: 2018-06-06 08:11:56 tags: 中间件 作者:李忠林Github: https://github.com/LeezhonglinGitblog: https://leezhonglin.github.io/日期: 2018年6月5日django中注册登录实现...
    title: 自定义django中间件实现登录
    date: 2018-06-06 08:11:56
    tags: 中间件
    

    作者:李忠林

    Github: https://github.com/Leezhonglin

    Gitblog: https://leezhonglin.github.io/

    日期: 2018年6月5日

    django中注册登录实现
    自定义中间件

    ​ 其实说django自己也带了中间件,但是用起来有点不灵活,需要验证的每个url前面需要包一层login_required(),自我感觉有点不方便.说干就干吧.

    首先在我们的项目文件夹下面创建一个新的目录专门用来存放我们中间件和其他函数.文件夹的名字我们就命名为:utils.在使用python manage.py startapp user 建立好我们用户的应用,所有与用户相关的东西都放这里面来.


    文件中的UserAuthMiddleware.py就是我们要自定义中间件的文件.init文件就是我们要去初始化中间件.

    下面我们就在UserAuthMiddleware.py中开始写我们的代码了.

    from datetime import datetimefrom django.db.models import Q
    from django.http import HttpResponseRedirect
    from django.core.urlresolvers import reverse
    from django.utils.deprecation import MiddlewareMixinfrom user.models import UserTicketModel
    ​
    ​
    class UserAuthMiddle(MiddlewareMixin):
    ​
        def process_request(self, request):
            # 验证cookie中的ticket,验证不通过,跳转到登录页面
            # 验证通过,request.user 就能获取当前登录的用户信息
            # path = request.path
            # 需要登录验证, 个人中心和购物车
            need_login = ['/axf/mine/', '/axf/cart/']
    ​
            if request.path in need_login:
                # 先获取cookie中的ticket的参数
                ticket = request.COOKIES.get('ticket')
                # 如果没有ticket 直接跳转到登录
                if not ticket:
                    return HttpResponseRedirect(reverse('user:login'))
                # 查询ticket对应的用户
                user_ticket = UserTicketModel.objects.filter(ticket=ticket).first()
                if user_ticket:
                    # 获取到有认证的相关信息
                    # 1. 验证当前认证信息是否过期,如果没有过期,request.user赋值
                    # 2. 如果过期了,跳转到登录,并删除认证信息
                    # --------------------------------- #
                    # 判断当期时间是否与服务器ticket的时间过期
                    # replace()将user_ticket.out_time中的tzinfo替换掉
                    if datetime.now() > user_ticket.out_time.replace(tzinfo=None):
                        # 过期 就删除这个用户认证的所有信息 并跳转到登录页面
                        UserTicketModel.objects.filter(user=user_ticket.user).delete()
                        return HttpResponseRedirect(reverse('user:login'))
                    else:
                        # 没有过期 ,赋值request.user ,并且删除多余的认证信息
                        request.user = user_ticket.user
                        #  删除多余的认证信息 ~Q取反
                        UserTicketModel.objects.filter(Q(user=user_ticket.user) & ~Q(ticket=ticket)).delete()
                        return None
                else:
                    return HttpResponseRedirect(reverse('user:login'))
            else:
                return None

    引入模块的顺序是先引入系统自带的模块—>在引入django带的模块—>在引入自己定义的模块.已经登录注册的中间件我们就定义好了.那么我们如何去使用它呢?

    进入我们的项目中的settings.py的文件找到我们的中间件配置的位置把我们定义好的东西引入进来具体如下:

    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',
        # 下面这个就是我们定义好的中间件了
        'utils.UserAuthMiddleWare.UserAuthMiddle',  
    ]

    再来到我们定义好的models.

    from django.db import models
    ​
    ​
    class UesrModel(models.Model):
        """
        保存用户
        """
        username = models.CharField(max_length=32, unique=True)
        password = models.CharField(max_length=256)  # 密码
        email = models.CharField(max_length=64, unique=True)
        # False 代表女
        sex = models.BooleanField(default=False)  # 性别
        icon = models.ImageField(upload_to='icons')  # toux
        is_delete = models.BooleanField(default=False)  # 是否删除
    ​
        class Meta:
            db_table = 'axf_users'
    ​
    ​
    class UserTicketModel(models.Model):
        """
        保存用户登录需要用的ticket
        """
        user = models.ForeignKey(UesrModel)  # 关联用户
        ticket = models.CharField(max_length=256)  # 密码
        out_time = models.DateTimeField()  # 过期时间
    ​
        class Meta:
            db_table = 'axf_users_ticket'

    以上准备工作都做好了之后我们就开始来配置我们的[URL]和views.

    from django.conf.urls import urlfrom user import viewsurlpatterns = [
        # 注册
        url(r'^register/', views.register, name='register'),
        # 登录
        url(r'^login/', views.login, name='login'),
        # 注销
        url(r'^logout/', views.logout, name='logout'),
    ​
    ]

    建立我们的登录注册注销的views

    from datetime import datetime, timedeltafrom django.contrib.auth.hashers import make_password, check_password
    from django.core.urlresolvers import reverse
    from django.http import HttpResponse, HttpResponseRedirect
    from django.shortcuts import renderfrom user.models import UesrModel, UserTicketModel
    from utils.function import get_ticket
    ​
    ​
    def register(request):
        if request.method == 'GET':
            return render(request, 'user/user_register.html')
    ​
        if request.method == 'POST':
            username = request.POST['username']
            email = request.POST['email']
            password = request.POST['password']
            icon = request.FILES['icon']
    ​
            # 需要验证参数都不为空
            if not all([username, email, password]):
                #  验证不通过向页面返回信息
                msg = '参数不能为空'
                return render(request, 'user/user_register.html', {'msg': msg})
            # 加密 make_password()
            password = make_password(request.POST['password'])
            # 创建用户
            UesrModel.objects.create(username=username,
                                     email=email,
                                     password=password,
                                     icon=icon)
            # 跳转到登录页面
            return HttpResponseRedirect(reverse('user:login'))
    ​
    ​
    def login(request):
        """
        登录
        :param request:
        :return:
        """
        if request.method == 'GET':
            return render(request, 'user/user_login.html')
    ​
        if request.method == 'POST':
    ​
            username = request.POST.get('username')
            password = request.POST.get('password')
            # 验证用户是否存在
            user = UesrModel.objects.filter(username=username).first()
    ​
            if user:
                # 验证密码是否正确
                if check_password(password, user.password):
                    # 1. 保存ticket在客户端
                    ticket = get_ticket()
                    response = HttpResponseRedirect(reverse('axf:mine'))
                    # 获取系统时间 并使用timedelta函数 加一天为过期时间
                    out_time = datetime.now() + timedelta(days=1)
                    # 设置过期时间
                    response.set_cookie('ticket', ticket, expires=out_time)
                    # 2. 保存ticket 到服务器的user_ticket表中
                    UserTicketModel.objects.create(user=user,
                                                   out_time=out_time,
                                                   ticket=ticket)
    ​
                    return response
                else:
                    msg = '密码不正确'
                    return render(request, 'user/user_login.html', {'msg': msg})
            else:
                msg = '用户名不正常'
    ​
                return render(request, 'user/user_login.html', {'msg': msg})
    ​
    ​
    def logout(request):
        """
        用户注销
        """
        if request.method == 'GET':
            # 注销,删除当前登录的用户的cookies中的ticket信息
            response = HttpResponseRedirect(reverse('user:login'))
            response.delete_cookie('ticket')
            return response

    来到这一步我们的工作就差不多结束了.这样我们就可以启动服务器来测试我们定义的中间件是否有效. 推荐都使用debug来检查我们写代码的问题,这样对我们自己的能力提升是非常大的.

    ​ ——————<end>-------------

    展开全文
  • django 中间件 中间件Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。 创建工程和应用 django-admin startproject mySite python manage.py ...

    django 中间件

    中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。

    • call(self, request), response = self.get_response(request)获得的是此次要响应给客户端的响应,前后的代码,在客户端,发起请求后,接收到响应前各执行一次。
    1. 在 response = self.get_response(request)之前的代码段将在客户端,发起请求后,路由匹配前执行。
    2. 在response = self.get_response(request)之后的代码段将在向客户端响应请求前执行
    • process_view(request, view_func, *view_args, **view_kwargs),在url匹配后视图函数处理前调用,如果return None, 那么,调用完后执行url匹配后的视图函数
    • def process_exception(request, exception, *args),视图函数执行失败执行此函数

    创建工程和应用

    在 frequencylimit / frequencylimitmiddleware.py 下编写中间件类

    from django.http import HttpResponse
    
    # Create your views here.
    
    class SimpleMiddleware:
        def __init__(self, get_response):
            self.get_response = get_response
            # One-time configuration and initialization.
            print("中间件初始化,__init__")
    
        def __call__(self, request):
            # Code to be executed for each request before
            # the view (and later middleware) are called.
            print("经过下一个中间件之前,__call__")
    
            # 获得 process_view 返回的response 或 视图返回response
            response = self.get_response(request)
    
            # Code to be executed for each request/response after
            # the view is called.
            print("request.META['REMOTE_ADDR']", request.META["REMOTE_ADDR"])
    
            print("访问完视图,__call__")
            # print(response.__dict__)
            # content = response.__dict__['_container'][0].decode(encoding="utf8")
            # print("content:",content)
            return response
    
        # 如果return None,就访问视图 view_func(请求对应的后台处理程序)
        # 如果return HttpResope对象,那么就不会执行后台相应的程序
        def process_view(request, view_func, *view_args, **view_kwargs):
            print("访问视图前:process_view")
            # return HttpResponse("你还没访问到视图") 
    
        def process_exception(request, exception, *args):
            print("服务器出错了....",*args)
            return HttpResponse("服务器出错了....%")
    

    在index / view.py 编写视图

    from django.http import HttpResponse
    from django.shortcuts import render
    
    # Create your views here.
    def index(request):
        print("执行 index_views")
        raise KeyError
        return render(request, "index.html", {"content": "ok"})
    

    配置路由

    from django.contrib import admin
    from django.urls import path
    
    from index.views import index
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path("index/", index),
    ]
    

    设置 settings

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # 注册应用
        'index',
        'frequencylimit',
    ]
    
    MIDDLEWARE = [
    	# 自定义的中间件
    	# 放在最上面,客户端的访问requst,按顺序从前往后经过中件间的检查,最后访问后台得到response,
    	# reponse按顺序从后往前过中件间的审视最后响应给客户端
        "frequencylimit.frequencylimitmiddleware.SimpleMiddleware",
        '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',
    ]
    

    执行结果

    System check identified no issues (0 silenced).
    March 07, 2019 - 10:22:17
    Django version 2.1.7, using settings 'webSite.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CTRL-BREAK.
    中间件初始化,__init__
    经过下一个中间件之前,__call__
    访问视图前:process_view
    执行 index_views
    服务器出错了....
    访问完视图,__call__
    [07/Mar/2019 10:22:24] "GET /index/ HTTP/1.1" 200 23
    

    在这里插入图片描述

    展开全文
  • 前戏 我们在前面的课程中已经学会了给视图函数加装饰器来判断是用户是否登录,把没有登录的用户请求跳转到登录页面。我们通过给几个特定视图函数加装饰器实现了这个需求。...官方的说法:中间件是一个用来处理D...
  •  自定义django中间件  什么是中间件?  django请求生命周期完整版,中间件类似于django的门卫,数据在进入和离开时都需要经过中间件 中间件能干嘛?  控制用户访问频率,全局登录校验,用户访问白名单,...
  • 自定义django中间件

    2020-09-08 15:08:22
    中间件是介于request 和...Django自定义中间件 继承自MiddlewareMixin。MiddlewareMixin里面实现了4个方法,自定义中间件时,只要重写这4个方法即可。 #方法一、处理请求之前:在request对象产生之后,url匹配之前调
  • Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。 我们可以使用...
  • 自定义中间件 1.创建文件来写自定义中间件,可以放在工程目录 2. 写入中间件类继承于MilldewareMixin类 from django.utils.deprecation import MiddlewareMixin class TestMiddleware(MiddlewareMixin): def ...
  • Django 中间件

    万次阅读 2020-09-09 10:16:52
    文章目录Django 中间件自定义中间件自定义中间件类的方法process_request 方法实例process_response实例process_view实例process_exception实例 Django 中间件 Django 中间件是修改 Django request 或者 response ...
  • Django自定义中间件

    2021-02-25 20:48:21
    Django自定义中间件 #自定义中间件类 from django.utils.deprecation import MiddlewareMixin from django.http import JsonResponse class MD1(MiddlewareMixin): def process_request(self, request): print('...
  • 主要介绍了详解Django中间件的5种自定义方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了详解django自定义中间件处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Django中间件

    2021-09-07 23:01:31
    文章目录django中间件如何自定义中间件1.必须掌握2.了解即可 django中间件 django中间件是django的门户 1.请求来的时候需要先经过中间件才能到达真正的django后端 2.响应走的时候最后也需要经过中间件才能发送出去...
  • django-自定义中间件

    2019-12-24 09:40:10
    自定义中间件 中间件所处的位置没有规定, 只要是放到项目中即可 一般分位两种情况 1.如果是中间件属于某个app, 那么可以在这app下面创建一个python文件用来存放中间件 2.如果是用来存放本项目中所有中间件, 可以在...
  • Django中间件 自定义中间件 中间件(类)中5种方法 中间件应用场景 回到顶部(go to top) Django中间件 在http请求 到达视图函数之前 和视图函数return之后,django会根据自己的规则在合适的时机执行...
  • django自定义中间件

    2019-10-15 19:54:15
    from django.utils.depracation import MiddlewareMixin 在类中根据功能需求,创建需求类,重新需求的方法 启用中间件,在settings中进行配置,MIDDLEWARE中注册中间件 app.middleware.中间件类名 详情如下: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,952
精华内容 2,780
关键字:

自定义django中间件