[1030 | Day56]ジャンゴミドルウェア

Djangoのミドルウェア

クッキーとセッションが終了した後、我々はデコレータのユーザーを追加することによって判断することを学んだにログインし、他のページにログアウトされたデータユーザにジャンプするためには、ユーザーのログイン状態を保ちます。

表現

しかし、我々は、特定のビュー機能のニーズにデコレータを追加することで実現し、かつそれぞれがビュー機能を追加した後デコレータ、とても迷惑を追加する必要があるかもしれません!

トーメント式

次のコンテンツは、我々は、上記の問題を解決する(すべて同じ操作を行うには同様の要求を達成するために)と始める完璧学ぶことができます!

1.知人ミドルウェア

1.1定義

まず、公式バージョンは再度行きます:

  • ミドルウェアは、グローバルジャンゴの入力と出力を変更するため、Djangoは軽量、低レベルのプラグインシステムで要求および応答を処理するためのフレームレベルのフックです。各ミドルウェアコンポーネントは、いくつかの特定の機能を実行する責任があります。

その後、白バージョンは再度行きます:

  • ビュー機能が実行される前と後のミドルウェアを行い、いくつかの追加の作業を行うために私たちを助けることができる、それは基本的にカスタムクラスで、クラスはいくつかのメソッドを定義して、Djangoフレームワークは、要求を処理するために特定の時刻に実行することになりますこれらのメソッド。

注意:世界的なミドルウェアの影響を受け、その使用に注意する必要があり、不適切な使用は、パフォーマンスに影響を与えることができます。

1.2の設定

ミドルウェア、英語、と私はそれを大声で読み:中東-ウェア

表現

これは、デジャヴ感ではないでしょうか?

私たちは、BMSシステムを記述する際はい、実際にミドルウェアへのアクセスを持っていました。

ときに大きなイエローページ........

漢も知らないときに当時のパスのための混乱Baiduの検索をするsettings.py際にコメント.........

まだそれを考えますか?

表現

それを忘れて、彼の顔を表示するように指示!

#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',
]

いくつかのものは、リスト、文字の文字列であるように見えるが、実際に一つのクラスである、またはメザニンです。

不信的话,Ctrl+Click试一下吧!

那么在之前,我们已经接触过一个CSRF相关的中间件了,就是那个被做(注释)掉的,哈哈开玩笑~

表現

注释掉之后提交post请求的时候,就不会被forbidden了。

后来学会使用csrf_token之后就不再注释这个中间件了。

那接下来就学习中间件中的方法以及这些方法什么时候被执行。

2. 自定义中间件

2.1 定义五个方法

分别是:

  • process_request(self,request)
  • process_view(self, request, view_func, view_args, view_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

以上方法的返回值可以是None或一个HttpResponse对象。

  • 如果是None,则继续按照django定义的规则向后继续执行
  • 如果是HttpResponse对象,则直接将该对象返回给用户。

示例:

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response

IMG

IMG

2.2 process_request

参数:

  • request
    • 这个request和视图函数中的request是一样的(在交给Django后面的路由之前,对这个request对象可以进行一系列的操作)。
    • 由于request对象是一样的,所以我们可以对request对象进行一系列的操作,包括request.变量名=变量值,这样的操作,我们可以在后续的视图函数中通过相同的方式即可获取到我们在中间件中设置的值。

返回值:

  • None
    • 返回值是None的话,按正常流程继续走,交给下一个中间件处理
  • HttpResponse

    • 如果是HttpResponse对象,Django将不执行视图函数,而将相应对象返回给浏览器

    IMG

执行顺序:

  • 按照中间件的注册顺序正序执行,且最先执行process_request

示例:

Step1>>>定义

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

Step2>>>注册

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',
    'middlewares.MD1',  # 自定义中间件MD1
    'middlewares.MD2'  # 自定义中间件MD2
]

Step3>>> 访问视图

MD1里面的 process_request
MD2里面的 process_request
app01 中的 index视图

Step4>>>调换Step2(M1/M2)注册顺序

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index视图

总结:

  • 调换顺序后,MD2比MD1先执行process_request
  • 视图函数最后执行
  • MD1和MD2的process_request中的request参数是同一个对象

2.3 process_response

参数:

  • request
    • 上述例子中一样的对象
  • response
  • 视图函数返回的HttpResponse对象
  • 也就是说这是Django后台处理完之后给出一个的一个具体的视图

返回值:

  • HttpResponse
    • 必须是,必须有!

执行顺序:

  • 按照中间件的注册顺序逆序执行,process_request之后,视图函数之前

示例:

Step1>>>定义

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

    def process_response(self, request, response):
        print("MD2里面的 process_response")
        return response

Step2>>>注册

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',
    'middlewares.MD2',  # 自定义中间件MD2
    'middlewares.MD1'  # 自定义中间件MD1
]

注意:此时注册顺序是先M2再M1!!!

Step3>>>访问视图

MD2里面的 process_request
MD1里面的 process_request
app01 中的 index视图
MD1里面的 process_response
MD2里面的 process_response

总结:

  • process_response方法是在视图函数之后执行的,并且顺序是MD1比MD2先执行
  • M2的process_response方法首先执行,而它的process_response方法最后执行

2.4 process_view

参数:

  • request
    • HttpRequest对象。
  • view_func
    • 是Django即将使用的视图函数
    • 它是实际的函数对象,而不是函数的名称作为字符串
  • view_args
    • 是将传递给视图的位置参数的列表
  • view_kwargs
    • 是将传递给视图的关键字参数的字典

返回值:

  • None

  • 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后再执行相应的视图

  • HttpResponse

    • 如果是HttpResponse对象,Django将不执行视图函数
    • 而是直接在中间件中掉头,倒叙执行一个个process_response方法,最后返回给浏览器

    IMG

执行顺序:

  • Django路由系统之后,视图系统之前执行
  • 按照中间件的注册顺序正序执行

示例:

Step1>>>定义

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD1 中的process_view")
        print(view_func, view_func.__name__)


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

    def process_response(self, request, response):
        print("MD2里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD2 中的process_view")
        print(view_func, view_func.__name__)

Step2>>>访问视图

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x000001DE68317488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x000001DE68317488> index
app01 中的 index视图
MD1里面的 process_response
MD2里面的 process_response

2.5 process_exception

参数:

  • request
    • HttpResponse对象
  • exception
    • 是视图函数异常产生的Exception对象

返回值:

  • None

    • 如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。
  • HttpResponse

    • 如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。

      IMG

执行顺序:

  • 按照中间件的注册顺序的倒序执行

示例:

Step1>>>定义

from django.utils.deprecation import MiddlewareMixin


class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD1 中的process_view")
        print(view_func, view_func.__name__)

    def process_exception(self, request, exception):
        print(exception)
        print("MD1 中的process_exception")


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

    def process_response(self, request, response):
        print("MD2里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD2 中的process_view")
        print(view_func, view_func.__name__)

    def process_exception(self, request, exception):
        print(exception)
        print("MD2 中的process_exception")
        

Step2>>>制造异常,否则无法发挥process_exception

def index(request):
    print("app01 中的 index视图")
    raise ValueError("呵呵")
    return HttpResponse("O98K")

Step3>>> 在MD1的process_exception中返回一个响应对象

class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD1 中的process_view")
        print(view_func, view_func.__name__)

    def process_exception(self, request, exception):
        print(exception)
        print("MD1 中的process_exception")
        return HttpResponse(str(exception))  # 返回一个响应对象

Step4>>>访问视图

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x0000022C09727488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x0000022C09727488> index
app01 中的 index视图
呵呵
MD1 中的process_exception
MD1里面的 process_response
MD2里面的 process_response

2.6 process_template_response(了解)

参数:

  • request
    • 一个HttpRequest对象
  • response
    • 是TemplateResponse对象(由视图函数或者中间件产生)

返回值:

  • render()

    • 视图函数返回的对象有一个render()方法

    • 或者表明该对象是一个TemplateResponse对象或等价方法

      IMG

执行顺序:

  • 在视图函数执行完成后立即执行

示例:

Step1>>>定义

class MD1(MiddlewareMixin):

    def process_request(self, request):
        print("MD1里面的 process_request")

    def process_response(self, request, response):
        print("MD1里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD1 中的process_view")
        print(view_func, view_func.__name__)

    def process_exception(self, request, exception):
        print(exception)
        print("MD1 中的process_exception")
        return HttpResponse(str(exception))

    def process_template_response(self, request, response):
        print("MD1 中的process_template_response")
        return response


class MD2(MiddlewareMixin):
    def process_request(self, request):
        print("MD2里面的 process_request")
        pass

    def process_response(self, request, response):
        print("MD2里面的 process_response")
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("-" * 80)
        print("MD2 中的process_view")
        print(view_func, view_func.__name__)

    def process_exception(self, request, exception):
        print(exception)
        print("MD2 中的process_exception")

    def process_template_response(self, request, response):
        print("MD2 中的process_template_response")
        return response
        

Step2>>>视图函数

def index(request):
    print("app01 中的 index视图")

    def render():
        print("in index/render")
        return HttpResponse("O98K")
    rep = HttpResponse("OK")
    rep.render = render
    return rep

ステップ3 >>>アクセス景色

MD2里面的 process_request
MD1里面的 process_request
--------------------------------------------------------------------------------
MD2 中的process_view
<function index at 0x000001C111B97488> index
--------------------------------------------------------------------------------
MD1 中的process_view
<function index at 0x000001C111B97488> index
app01 中的 index视图
MD1 中的process_template_response
MD2 中的process_template_response
in index/render
MD1里面的 process_response
MD2里面的 process_response

ダイ、今日の内容はコメント欄にあなたの賞賛を残すことを歓迎し、多くの、本当に多くあり、私たちは次の参照:)

表現

おすすめ

転載: www.cnblogs.com/fxyadela/p/11767368.html
おすすめ