【Django】クラスベースビューで関数のデコレータを使用する方法

Django

スポンサーリンク

Djangoは今どきクラスベースビューが主流なので、関数ベースビューをクラスベースビューに修正していた。

その中で、関数ベースビューで使っていたデコレータをクラスベースビューでどう実装するのかがわからなかったので、解説する。

※例として使うデコレータは「require_POST」(POSTリクエストのみ許可する)を使用

デコレータは関数ベースビューでは以下のように関数に「@require_POST」とつければよかった。

[views.py]

from django.views.decorators.http import require_POST

@require_POST
def post_only(request):
    ・・・以下省略・・・

クラスベースビューでは以下のように、「def dispatch」に「@method_decorator(require_POST)」を付与するとできる。

[views.py]

from django.views.generic import CreateView
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_POST

class AnswerCreateView(CreateView):
    def post(self, request, *args, **kwargs):
        ・・・以下省略・・・

    # POSTリクエストのみ受け付ける
    @method_decorator(require_POST)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

また、より簡潔に書きたいならば、クラスをデコレートすることもできます。この書き方ならば、「def dispatch」は定義する必要はありません。

@method_decorator(require_POST, name='dispatch')
class AnswerCreateView(CreateView):
    def post(self, request, *args, **kwargs):
        ・・・以下省略・・・

ちなみに、複数の同じデコレータが複数のクラスで呼ばれる場合は、デコレータのリスト(or タプル)を定義して、それをmethod_decorator()に渡しても良いです。

decorators = [login_required, require_POST]

@method_decorator(decorators, name='dispatch')
class AnswerCreateView(CreateView):
    def post(self, request, *args, **kwargs):
        ・・・以下省略・・・

これは以下のように作るのと同じ意味です。

@method_decorator(login_required, name='dispatch')
@method_decorator(require_POST, name='dispatch')
class AnswerCreateView(CreateView):
def post(self, request, *args, **kwargs):
・・・以下省略・・・

ちなみに複数のデコレータをつけた場合は、上にあるものから順に処理されます。

Django

Posted by ton