サイトアイコン ITC Media

UserPassesTestMixinの使い方を徹底解説|実例付

connect

(最終更新月:2021年12月)

「ログインの有無以外で、ユーザーのアクセスを制限したい!」

「独自のアクセス制限クラスを作れるようになりたい!」

というDjango初学者の方へ向けての記事となります

当記事を通じて、

について解説していきます

✔独学におすすめ

UserPassesTestMixinの基本

【書き方】

  1. 「UserPassesTestMixin」クラスのインポート
  2. 継承クラスの作成
  3. test_func関数の定義(Trueでアクセス可、Falseでアクセス不可)
  4. 3で不可の時のリダイレクト先を指定(handle_no_permission関数

【適用方法】

LoginRequiredMixinなどと同様、引数として最初に持ってくること

百聞は一見に如かず

実例をご覧頂いたほうが早いので下記へお進みください

【実例】UserPassesTestMixinクラスを作る

開発中の日報アプリでの一例となります

class OwnerOnly(UserPassesTestMixin):
    def test_func(self):
        nippo_instance = self.get_object()
        return nippo_instance.user == self.request.user
    
    def handle_no_permission(self):
        return redirect("nippo-detail", pk=self.kwargs["pk"])

test_func関数では、日報のユーザーとログインしているユーザーが一致しているかどうかをBool型で返すよう指示しています

handle_no_permission関数では、編集ページではなく詳細ページへ飛ぶように指示しています

UpdateViewへ適用していくので、UpdateViewで使えるメソッドは全て使えるという前提でコードを書いています

【実例】アクセス制限の適用

独自のクラスが作成できたら、対象のビューへ適用しましょう

方法は、LoginRequiredMixinと同様です

class NippoUpdateFormView(OwnerOnly, UpdateView):
    template_name = "nippo/nippo-formclass.html"
    model = NippoModel
    form_class = NippoModelForm
    success_url = reverse_lazy("nippo-list")

必ず他の継承クラスより前に継承しましょう

削除ページにも同じように設定し完了です

class NippoDeleteView(OwnerOnly, DeleteView):
    template_name = "nippo/nippo-delete.html"
    model = NippoModel
    success_url = reverse_lazy("nippo-list")

【補足】ビュー関数「user_passes_test」

流れとしては、

  1. Bool型(True or False)を返す関数の定義
  2. 関数をuser_passes_test()でデコレートする

【実例サンプル】

from django.contrib.auth.decorators import user_passes_test

#test_func同様アクセス制限の為の関数
def email_check(user):
    return user.email.endswith('@sample.com')

#デコレータを使い、アクセス制限を適用
@user_passes_test(email_check)
def index(request):
    ...

こちらの例では、email_checkというテスト関数Trueの場合はアクセス可能Falseの場合はアクセス不可、としています

まとめ

当記事を通じて、アクセスを制限するクラス、関数についてご説明させて頂きました

どちらも流れとしては、

  1. アクセスの可否を判断する関数の定義
  2. ビュークラス、ビュー関数に定義した関数(クラス)を適用

することが必要です

UserPassesTestMixinクラスについては、

  1. test_func関数で可否を判断するための処理を記述
  2. handle_no_permission関数でリダイレクト先を指定
  3. 作成したクラスをビュークラスへ適用

となります

user_passes_testデコレータについては、

  1. アクセスの可否を判断するための関数を定義
  2. @user_passes_test(作成した関数)デコレータでビュー関数へ適用

することが必要になります

さて、当記事を通じて自身の日報以外で編集・削除ページへはアクセスができなくなりました

ただ、現状は単に詳細ページへ飛んでしまうだけ

何かしらで「お知らせ」する必要がありますので、次回の記事を通じて「メッセージフレームワークの基本」を解説し、新たな機能を追加していきます

モバイルバージョンを終了