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

※本サイトにはプロモーション・広告が含まれています。

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

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

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

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

当記事を通じて、

  • 独自でアクセス制限を指定できるクラス「UserPassesTestMixin」の書き方と適用方法
  • 実例として、ForeignKeyで紐づけられたユーザーのみアクセスできるクラスの作成
  • 補足として、ビュー関数でのアクセス制限方法「user_passes_test」デコレータの書き方

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

✔YouTube解説動画

当記事の内容は動画を見ながら進めると、約15分程度で完了します。

動画ならではの情報も解説しているので、記事と一緒にご覧ください。

動画の概要欄には、単元ごとのコードを紹介しているgithubページも載せています。

✔独学におすすめ

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

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(作成した関数)デコレータでビュー関数へ適用

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

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

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

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

タイトルとURLをコピーしました