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

connectDjango

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

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

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

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

当記事を通じて、

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

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

【著者プロフィール】

profile_icon
【Python歴】11年 x 【Django歴】10年
HP作成、社内システムの構築、コンサルティング

当ブログを通じて、Webアプリの書き方やアプリの公開方法までを解説しています。

☆日報アプリ「D-Repo」(デモ版)→こちら

※Djangoをベースに作成したアプリです。

☆便利ツールアプリ「Tool Station」→こちら

※Django REST frameworkとReactで作成しているアプリです。

✔YouTube解説動画

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

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

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

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

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

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

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

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

✔当ブログは以下のような方に向けて書かれています

「Djangoでのアプリ開発を学びたい!」

「Djangoで開発したアプリをWebで公開するにはどうするの?」

✔当ブログ掲載の記事

  • Djangoで作る日報アプリ開発
  • WebアプリをWeb上に公開する方法
  • Webアプリ開発に必要なそのほかの情報
【Django】チュートリアル|日報アプリの開発から公開まで
Djangoのチュートリアルをお探しですか?具体的に「手を動かして作ってみたい!」という方へ向けて、誰でもできる簡易的な日報アプリの開発を通じて、Djangoの様々な機能に触れていくシリーズとなっています。PythonでWebアプリを作りたい方、必見の記事となります!

ITCブログにご協力いただける方は、以下もご検討いただけると嬉しいです。

ITCへ投げ銭をする

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