如何在django中编写自定义装饰器?

use*_*990 50 python django permissions decorator

问题 -

@is_premium_user
def sample_view:
          .......
          ......
Run Code Online (Sandbox Code Playgroud)

我希望某些视图只能访问网站的高级用户.
如何在我的项目中的各种应用程序中使用此装饰器?

Pho*_*beB 52

玩上面的各种链接,无法让他们工作,然后遇到了这个非常简单的我适应.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
Run Code Online (Sandbox Code Playgroud)

使用@wraps更好的比手动重写喜欢做wrap.__doc__ = fn.__doc__.除此之外,它还确保您的包装函数与包装函数具有相同的名称.

请参阅https://docs.python.org/2/library/functools.html


ari*_*rie 50

您不必为此编写自己的装饰器,因为user_passes_test已经包含在Django中.

并且有一个片段(group_required_decorator)扩展了这个装饰器,它应该非常适合您的用例.

如果你真的想写自己的装饰,那么网上有很多很好的文档.

好吧,为了(重新)使用装饰器,只需将装饰器放在路径上的模块中,然后就可以从任何其他模块导入它.


thn*_*nee 5

感谢arie,答案有很长的路要走,但这对我不起作用.

当我找到这个片段时,我让它正常工作: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
Run Code Online (Sandbox Code Playgroud)

装饰者

我把它放在我的顶部views.py,因为它太短了.

def membership_required(fn=None):
    decorator = user_passes_test(my_custom_authenticated)
    if fn:
        return decorator(fn)
    return decorator
Run Code Online (Sandbox Code Playgroud)

使用它

@membership_required
def some_view(request):
    ...
Run Code Online (Sandbox Code Playgroud)