DjangoのClass-Based Viewで権限確認を行う

DjangoでClass-Based ViewによるDetailView等を実装している際に、そのViewへのアクセスの可否をカスタムで確認したい場合があると思います。
例えば下記の様なモデルのDetailViewにおいて、各ユーザー自分のデータしか見れないようにする、などと言った場面です。

class Memo(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
path('memo/<int:pk>', views.MemoDetailView.as_view(),
         name='memo_detail'),
class MemoDetailView(DetailView):
    model = models.Memo

このままだと memo/2 のような適当な URL を入れることで誰でも閲覧可能になってしまいます。これを自分の Memo しか見れないようにします。

このような場面のためにテスト用のclassが用意されています。

test_func で OK/NG を Bool で返せば良いので、今回の場合だと下記のようなclassを作成し

class ObjectOwnerCheckMixin(UserPassesTestMixin):
    def test_func(self):
        login_user = self.request.user
        object_owner = self.get_object().user
        return login_user == object_owner

View側ではそれを継承すればOKです。

class MemoDetailView(ObjectOwnerCheckMixin,DetailView):
    model = models.Memo

27