(最終更新月:2021年12月)
「ログインの有無以外で、ユーザーのアクセスを制限したい!」
「独自のアクセス制限クラスを作れるようになりたい!」
というDjango初学者の方へ向けての記事となります
当記事を通じて、
- 独自でアクセス制限を指定できるクラス「UserPassesTestMixin」の書き方と適用方法
- 実例として、ForeignKeyで紐づけられたユーザーのみアクセスできるクラスの作成
- 補足として、ビュー関数でのアクセス制限方法「user_passes_test」デコレータの書き方
について解説していきます
UserPassesTestMixinの基本
【書き方】
- 「UserPassesTestMixin」クラスのインポート
- 継承クラスの作成
- test_func関数の定義(Trueでアクセス可、Falseでアクセス不可)
- 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」
流れとしては、
- Bool型(True or False)を返す関数の定義
- 関数を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の場合はアクセス不可、としています
まとめ
当記事を通じて、アクセスを制限するクラス、関数についてご説明させて頂きました
どちらも流れとしては、
- アクセスの可否を判断する関数の定義
- ビュークラス、ビュー関数に定義した関数(クラス)を適用
することが必要です
UserPassesTestMixinクラスについては、
- test_func関数で可否を判断するための処理を記述
- handle_no_permission関数でリダイレクト先を指定
- 作成したクラスをビュークラスへ適用
となります
user_passes_testデコレータについては、
- アクセスの可否を判断するための関数を定義
- @user_passes_test(作成した関数)デコレータでビュー関数へ適用
することが必要になります
さて、当記事を通じて自身の日報以外で編集・削除ページへはアクセスができなくなりました
ただ、現状は単に詳細ページへ飛んでしまうだけ
何かしらで「お知らせ」する必要がありますので、次回の記事を通じて「メッセージフレームワークの基本」を解説し、新たな機能を追加していきます