LoginSignup
28
27

More than 5 years have passed since last update.

DjangoでViewのデコレーターをurls.pyに書くと一覧性が高くなる

Last updated at Posted at 2016-04-24

DjangoでViewのデコレーターは通常views.pyに書きますが、これをurls.pyに書くようにすると一覧性が高くなるのでお勧めです。

通常の使い方(views.pyでデコレーターを指定)

複数のViewがあって各Viewの実装が大きくなってくると、どのViewにどんなデコレーターが指定されているのかが確認しにくくなってきます。

views.py
def view1(request):
    :
    # 長〜い処理
    :

@login_required
@staff_member_required
def view2(request):
    :
    # 長〜い処理
    :

@login_required
@has_permission('xxx')
def view3(request):
    :
    # 長〜い処理
    :

@login_required
@has_permission('xxx')
def view4(request):
    :
    # 長〜い処理
    :

※説明を簡略化する為、あえて関数ベースViewで書いています。

urls.pyでデコレーターを指定する

urls.pyは基本的にView1つに対して1行のコードを書くだけなので、ここでデコレーターを指定できると一覧性が高そうです。
urls.pyでデコレーターを指定するには次のように書きます。

urls.py
urlpatterns = [
    url(r'^$', login_required(has_permission('xxx')(views.view4)))
]

このままだと複数のデコレーターを使用する場合に入れ子になって読みにくいので、デコレータ指定用の関数を作成して使用します。

urls.py
def decorate(view_func, decorators):
    for decorator in reversed(decorators):
        view_func = decorator(view_func)

urlpatterns = [
    url(r'^$', decorete(views.view4, [login_required, has_permission('xxx')]))
]

更に、デコレーターの指定は同じ組み合わせを使うことが多いので、これらのパターンを定数として定義しておきます。

# ログインなしでアクセス可能
PUBLIC = []

# 中の人のみアクセス可能
STAFF_ONLY = [
    login_required,
    staff_member_required,
]

# 権限xxxを持つ人のみアクセス可能
XXX = [
    login_required,
    has_permission('xxx'),
]

これで各Viewの指定を確認しやすくすることが出来ました。

urls.py
urlpatterns = [
    url(r'^view1/$', decorate(views.view1, PUBLIC)),
    url(r'^view2/$', decorate(views.view1, STAFF_ONLY)),
    url(r'^view3/$', decorate(views.view2, XXX)),
    url(r'^view4/$', decorate(views.view3, XXX)),
]

こんなのもありました

こちらはinclude()に対してもデコレーターを指定できるようです。

28
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
27