web-dev-qa-db-ja.com

djangoでカスタムデコレータを書く方法は?

問題 -

@is_premium_user
def sample_view:
          .......
          ......

.

49
user677990

このために独自のデコレータを記述する必要はありません user_passes_test はすでにDjangoに含まれています。

そしてスニペットがあります( group_required_decorator )このデコレータを拡張し、ユースケースに非常に適しているはずです。

独自のデコレータを作成したい場合は、ネット上に多くの good documentation があります。

また、デコレータを(再)使用するには、デコレータをパス上のモジュールに配置するだけで、他のモジュールからインポートできます。

49
arie

上記のさまざまなリンクをいじってみて、それらを機能させることができず、私が適応させたこの本当に簡単なものに出くわしました。 http://code.activestate.com/recipes/498217-custom-Django-login_required-decorator/

from functools import wraps
from Django.http import HttpResponseRedirect

def authors_only(function):
  @wraps(function)
  def wrap(request, *args, **kwargs):

        profile = request.user.get_profile()
        if profile.usertype == 'Author':
             return function(request, *args, **kwargs)
        else:
            return HttpResponseRedirect('/')

  return wrap

@wrapsの使用は、wrap.__doc__ = fn.__doc__のように手動でオーバーライドするよりもbetterです。とりわけ、ラッパー関数がラップされた関数と同じ名前を取得することを保証します。

https://docs.python.org/2/library/functools.html を参照してください

49
PhoebeB

アリエのおかげで、答えは大いに役立ちましたが、私にはうまくいきません。

このスニペットを見つけたとき、適切に動作するようになりました: http://djangosnippets.org/snippets/983/

このソリューションは私のために働いた:

ヘルパー関数

この関数には、user.is_authenticatedに代わるドロップインとして、他の場所で再利用できるという利点があります。たとえば、テンプレートタグとして公開できます。

def my_custom_authenticated(user):
    if user:
        if user.is_authenticated():
            return user.groups.filter(name=settings.MY_CUSTOM_GROUP_NAME).exists()
    return False

デコレータ

短いので、これをviews.pyの一番上に配置しました。

def membership_required(fn=None):
    decorator = user_passes_test(my_custom_authenticated)
    if fn:
        return decorator(fn)
    return decorator

それを使用する

@membership_required
def some_view(request):
    ...
5
thnee

Django自体の例を参照してください:

http://code.djangoproject.com/browser/Django/trunk/Django/contrib/auth/decorators.py

あなたの特定の例は、おそらくテストが「プレミアム」グループのメンバーシップになる「user_passes_test」の単なるバージョンです。

どこでも使用するには、pythonパッケージを作成し、そこからインポートします。sys.pathにある限り、検出されます。

2
Spacedman

http://www.makina-corpus.org/blog/permission-required-decorator-Django

私はそのブログ投稿をベースにしました。

これをpythonパスのファイルまたは「util」アプリに貼り付けて、ビューにインポートします。

e.g。

project_dir
|_ app1
|_ app2
|_ utils
   |_ __init__.py
   |_ permreq.py


from util.permreq import permission_required

@permmission_required('someapp.has_some_perm', template='denied.html')
def some_view(request):
    blah blah
1
DTing

検証が失敗したときにリダイレクトするページとエンドユーザーに表示するメッセージを指定するために追加のパラメーターを許可する、わずかに異なる実装を次に示します。

from functools import wraps
from Django.core.urlresolvers import reverse
from Django.http import HttpResponseRedirect
from core.helpers.flash import send_flash_error

def lender_only(redirect_to='plateforme.views.vue_login', error_flash_message=None):
  def inner_render(fn):
    @wraps(fn)  # Ensure the wrapped function keeps the same name as the view
    def wrapped(request, *args, **kwargs):
      if request.context.user.is_authenticated and request.context.user.is_lender:
        return fn(request, *args, **kwargs)
      else:
        if error_flash_message:
          send_flash_error(request, error_flash_message) # Replace by your own implementation

        return HttpResponseRedirect(reverse(redirect_to))
    return wrapped
  return inner_render

# Usage:
@lender_only('vitrine.views.projets', {'message': "Oops, can't go there."})
def render_page_index(request):

このガイドは、私がそれを理解するのに役立ちました: https://elfsternberg.com/2009/11/20/python-decorators-with-arguments-with-bonus-Django-goodness/ 以前の回答

0
Vadorequest