1この記事を三行にまとめるとbeforeFilterやbeforeRenderのような処理を実装できますミドルウェアの中で処理を場合分けしなきゃいけないメリットは大きいと思うので何とか使いこなせるようになりたいですね例えばページが読み込まれた時、どのページでも共通の処理が走るようにしたい場合、CakePHPだとAppControllerのbeforeFilterやbeforeRenderに処理を書いて、各コントローラーでクラスを継承するというやり方があります。}}これと同じようなことをDjangoで実現したい場合にミドルウェアという機能があります。今日はそのミドルウェアを使ってみましょう。CakePHPにもミドルウェアという機能はありますが、あっちは玉ねぎのようにアプリケーションを包み込む機能だっていう噂なので、Djangoのミドルウェアとは根本的に違......くもないのかな。そのミドルウェアを使えばbeforeFilterやbeforeRenderのような処理を実装できます。ミドルウェアの読み込みミドルウェアを読み込むためにはミドルウェア用のpyファイルを作成し、settings.pyで読み込みの設定を記述する必要があります。今、アプリケーションフォルダの中に「auth.py」というミドルウェアのファイルを作成したとしましょう。settings.py絶対にmiddlewaresというフォルダ名じゃないといけないわけではないですが、今回はこの構成でいきます。auth.pyの中身はざっくりこんな感じです。response)これをsettings.pyで読み込みます。settings.pyを開くと「MIDDLEWARE」という変数があると思います。'django.middleware.clickjacking.XFrameOptionsMiddleware',]ここに自作のミドルウェアを追加します。#これを追加]importする時と同じような書き方ですね。これでどのページにアクセスした時もAuthMiddlewareが読み込まれるようになります。呼び出されるタイミング先ほどAuthMiddlewareの中に四つほどメソッドを書きましたが、それぞれのメソッドは呼び出しのタイミングが異なります。「__init__.py」はサーバーが起動した時に一回だけ読み込まれます。runserverで起動した時とかApacheを起動した時の最初の一回だけです。その後は何回ページを読み込み直しても__init__.pyは呼ばれない。「__call__.py」は何かしらのページにアクセスした時に最初に読み込まれます。CakePHPで言うと......何だろ、bootstrap.phpとかが読み込まれるタイミングに似ているのかな。この二つは今日は置いときましょう。今回はbeforeFilterやbeforeRenderに相当するところを見たいので、残りの「process_view」や「process_template_response」を重点的に触れていきます。process_viewprocess_viewはビューが読み込まれる直前に呼び出されるメソッドです。beforeFilterに相当する部分がこれにあたると考えて良いと思います。GETパラメータに特定の値が入ってなかったらエラーページに飛ばすみたいな処理はここで書くことができる。redirect('/error')「https://norm-nois.com/users/index?token=sampletoken」みたいな感じでアクセスした時にパラメータのtokenをチェックするみたいな処理です。「__call__.py」でも同じような動きを実装できると思うんですが、じゃあ__call__.pyとの使い方は何が違うのよって言うと、僕も正直あまりよく分かってないんですが一つは「kwargs」などの引数が使えるっていう点ですかね。「https://norm-nois.com/novels/short/t/853」というURLにアクセスできるように設定を行なったとする。853}こんな感じでkwargsでURLのIDを取れたりします。このIDを使って何か処理を行なったり、あるいはIDがなかった時にエラーページに飛ばしたりできます。process_template_responseprocess_template_responseはビューが実行された後に読み込まれるので、beforeRenderに近いタイミングと考えて良いと思います。context)#index.html{{title}}こんな感じですね。process_template_responseはTemplateResponseでページを出力している場合に有効なメソッドになるようです。ドキュメントを見るとrender関数で読み込んでる場合なども有効だーみたいなことが書いてあるんですが、僕がやった限りではrenderだと上手く動かなかったです。HttpResponse()この書き方の場合はいずれもprocess_template_responseが機能しませんでした。HttpResponseの方はテンプレートをレンダリングしてないんで動かないのはドキュメント通りなのですが。すまん、今の俺には分からん。特定のURLの時だけ処理を実行したいCakePHPの場合、共通の処理を行いたくないコントローラーでAppControllerを継承しない、あるいはbeforeFilterやbeforeRenderでAppControllerのそれらを呼び出さないようにすれば回避することができるんですが、Djangoのミドルウェアの場合は特定のURLでだけ読み込まないようにすると言った処理はできないみたいです。それをやりたければミドルウェアの中で処理を場合分けしなきゃいけない。#トークンチェック処理を入れるこんな風にURLにトークンがあるかどうかを見て、ある場合は認証が必要だと判断する。URLの場合はユーザーが簡単に書き換えられてしまうんで、本当は認証が必要なページなのに意図的にそれを回避されてしまうかもしれない。いろんなやり方が考えられるとは思いますが、例えばurls.pyでURLに必ず特定のパラメータを渡せるようにする方法が考えられます。urls.pyでURLにauthというパラメータを渡せるように設定しています。一例ですが、こうすれば「https://norm-nois.com/novels/index」の方ではauthパラメータを渡してないので認証は行われず、「https://norm-nois.com/novels/short」の方のみ認証チェックの処理を行うようにできます。CakePHPのbeforeFilterやbeforeRenderに比べると若干クセがあるような気もしますが、でも処理が共通化できるメリットは大きいと思うので、何とか使いこなせるようになりたいですね。今回は触れませんでしたが、エラーが発生した時の「process_exception」などもあります。詳細はこちら(↓)にあるのでもう少し情報が欲しいという場合はぜひに。与太話phpMyAdminMySQLLinuxブラウザ旅行その他プロット作成をお助け小説出版しましたYouTubeはじめましたTwitterやってます。