Djangoの詳細画面(DetailView)で自分以外のユーザページにアクセス出来ないようにする方法

Djangoの詳細画面(DetailView)で自分以外のユーザページにアクセス出来ないようにする方法をご紹介します。

条件

  • Django 2.1.3
  • Python 3.7.0

UserPassesTestMixin

クラスベースviewsには、UserPassesTestMixinというクラスが用意されており、指定した条件を満たさない場合に403エラーとすることが出来ます。

https://docs.djangoproject.com/ja/2.1/topics/auth/default/#django.contrib.auth.mixins.UserPassesTestMixin

実装例1

以下では、詳細画面(DetailView)において、表示する画面がログインユーザ中のpkと異なる場合403エラーになります。
(ただしsuperuserはOK)

# views.py抜粋
class DetailView(LoginRequiredMixin, UserPassesTestMixin, generic.DetailView):
    model = MyModel
    template_name = 'monitor/detail.html'

    def test_func(self):
        # pkが現在ログイン中ユーザと同じ、またはsuperuserならOK。
        current_user = self.request.user
        return current_user.pk == self.kwargs['pk'] or current_user.is_superuser

実行結果(ログインユーザ中のpkと異なる場合)

実装例2

以下のように独自のテストクラスを複数定義して、任意のviewに渡すことで複数条件のチェックを行うこともできます。

# views.py抜粋
class TestMixin1(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.email.endswith('@example.com')

class TestMixin2(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.username.startswith('django')

class MyView(TestMixin1, TestMixin2, View):
    ...

参考

同様に、関数ベースviewでは「user_passes_test」が用意されています。

https://docs.djangoproject.com/ja/2.1/topics/auth/default/#limiting-access-to-logged-in-users-that-pass-a-test
Django

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です