問題 -
@is_premium_user
def sample_view:
.......
......
.
このために独自のデコレータを記述する必要はありません user_passes_test
はすでにDjangoに含まれています。
そしてスニペットがあります( group_required_decorator
)このデコレータを拡張し、ユースケースに非常に適しているはずです。
独自のデコレータを作成したい場合は、ネット上に多くの good documentation があります。
また、デコレータを(再)使用するには、デコレータをパス上のモジュールに配置するだけで、他のモジュールからインポートできます。
上記のさまざまなリンクをいじってみて、それらを機能させることができず、私が適応させたこの本当に簡単なものに出くわしました。 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です。とりわけ、ラッパー関数がラップされた関数と同じ名前を取得することを保証します。
アリエのおかげで、答えは大いに役立ちましたが、私にはうまくいきません。
このスニペットを見つけたとき、適切に動作するようになりました: 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):
...
Django自体の例を参照してください:
http://code.djangoproject.com/browser/Django/trunk/Django/contrib/auth/decorators.py
あなたの特定の例は、おそらくテストが「プレミアム」グループのメンバーシップになる「user_passes_test」の単なるバージョンです。
どこでも使用するには、pythonパッケージを作成し、そこからインポートします。sys.pathにある限り、検出されます。
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
検証が失敗したときにリダイレクトするページとエンドユーザーに表示するメッセージを指定するために追加のパラメーターを許可する、わずかに異なる実装を次に示します。
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/ 以前の回答