**from** django.contrib.auth.decorators **import** user_passes_test
**def** **group\_required**(*group_names):
"""Requires user membership in at least one of the groups passed in."""
**def** **in\_groups**(u):
**if** u.is_authenticated():
**if** bool(u.groups.filter(name__in=group_names)) | u.is_superuser:
**return** **True**
**return** **False**
**return** user_passes_test(in_groups)
# The way to use this decorator is:
@group\_required('admins', 'seller')
**def** **my\_view**(request, pk):
... django.contrib.auth.decorators **import** user_passes_test
**def** **group\_required**(*group_names):
"""Requires user membership in at least one of the groups passed in."""
**def** **in\_groups**(u):
**if** u.is_authenticated():
**if** bool(u.groups.filter(name__in=group_names)) | u.is_superuser:
**return** **True**
**return** **False**
**return** user_passes_test(in_groups)
# The way to use this decorator is:
@group\_required('admins', 'seller')
**def** **my\_view**(request, pk):
...
有关此装饰器更多的介绍,可以参考 这里 。
Anonymous required
这个装饰器是参考Django自带的 login_required
装饰器,但是功能是相反的情况,即用户必须是未登录的,否则用户将被重定向到 settings.py
中定义的地址。当我们想要已登录的用户不允许进入某些视图(比如登录)时,非常有用。
**def** **anonymous\_required**(function=None, redirect_url=None):
**if** **not** redirect_url:
redirect_url = settings.LOGIN_REDIRECT_URL
actual_decorator = user_passes_test(
**lambda** u: u.is_anonymous(),
login_url=redirect_url
)
**if** function:
**return** actual_decorator(function)
**return** actual_decorator
# The way to use this decorator is:
@anonymous\_required
**def** **my\_view**(request, pk):
... **anonymous\_required**(function=None, redirect_url=None):
**if** **not** redirect_url:
redirect_url = settings.LOGIN_REDIRECT_URL
actual_decorator = user_passes_test(
**lambda** u: u.is_anonymous(),
login_url=redirect_url
)
**if** function:
**return** actual_decorator(function)
**return** actual_decorator
# The way to use this decorator is:
@anonymous\_required
**def** **my\_view**(request, pk):
...
有关此装饰器更多的介绍,可以参考 这里 。
Superuser required
这个装饰器和上面的 group_required
类似, 但是它只允许超级用户才能访问视图。
**from** django.core.exceptions **import** PermissionDenied
**def** **superuser\_only**(function):
"""Limit view to superusers only."""
**def** **\_inner**(request, *args, **kwargs):
**if** **not** request.user.is_superuser:
**raise** PermissionDenied
**return** function(request, *args, **kwargs)
**return** _inner
# The way to use this decorator is:
@superuser\_only
**def** **my\_view**(request):
... django.core.exceptions **import** PermissionDenied
**def** **superuser\_only**(function):
"""Limit view to superusers only."""
**def** **\_inner**(request, *args, **kwargs):
**if** **not** request.user.is_superuser:
**raise** PermissionDenied
**return** function(request, *args, **kwargs)
**return** _inner
# The way to use this decorator is:
@superuser\_only
**def** **my\_view**(request):
...
有关此装饰器更多的介绍,可以参考 这里 。
Ajax required
这个装饰器用于检查请求是否是AJAX请求,在使用jQuery等Javascript框架时,这是一个非常有用的装饰器,也是一种保护应用程序的好方法。
**from** django.http **import** HttpResponseBadRequest
**def** **ajax\_required**(f):
"""
AJAX request required decorator
use it in your views:
@ajax\_required
def my\_view(request):
....
"""
**def** **wrap**(request, *args, **kwargs):
**if** **not** request.is_ajax():
**return** HttpResponseBadRequest()
**return** f(request, *args, **kwargs)
wrap.__doc__ = f.__doc__
wrap.__name__ = f.__name__
**return** wrap
# The way to use this decorator is:
@ajax\_required
**def** **my\_view**(request):
... django.http **import** HttpResponseBadRequest
**def** **ajax\_required**(f):
"""
AJAX request required decorator
use it in your views:
@ajax\_required
def my\_view(request):
....
"""
**def** **wrap**(request, *args, **kwargs):
**if** **not** request.is_ajax():
**return** HttpResponseBadRequest()
**return** f(request, *args, **kwargs)
wrap.__doc__ = f.__doc__
wrap.__name__ = f.__name__
**return** wrap
# The way to use this decorator is:
@ajax\_required
**def** **my\_view**(request):
...
有关此装饰器更多的介绍,可以参考 这里 。
Time it
如果您需要改进某个视图的响应时间,或者只想知道运行需要多长时间,那么这个装饰器非常有用。
**def** **timeit**(method):
**def** **timed**(*args, **kw):
ts = time.time()
result = method(*args, **kw)
te = time.time()
print('%r (%r, %r) %2.2f sec' % (method.__name__, args, kw, te - ts))
**return** result
**return** timed
# The way to use this decorator is:
@timeit
**def** **my\_view**(request):
... **timeit**(method):
**def** **timed**(*args, **kw):
ts = time.time()
result = method(*args, **kw)
te = time.time()
print('%r (%r, %r) %2.2f sec' % (method.__name__, args, kw, te - ts))
**return** result
**return** timed
# The way to use this decorator is:
@timeit
**def** **my\_view**(request):
...
有关此装饰器更多的介绍,可以参考 这里 。
自定义功能
下面这个装饰器只是一个示例,测试你能够轻松地检查某些权限或某些判断条件,并100%自己定制。
想象你有一个博客、购物论坛,如果用户需要有很多积分才能发表评论,这是一个避免垃圾信息的好方法。下面创建一个装饰器来检查用户是否已登录并拥有超过10个积分,这样才可以发表评论,否则将抛出一个Forbidden。
**from** django.http **import** HttpResponseForbidden
logger = logging.getLogger(__name__)
**def** **user\_can\_write\_a\_review**(func):
"""View decorator that checks a user is allowed to write a review, in negative case the decorator return Forbidden"""
@functools.wraps(func)
**def** **wrapper**(request, *args, **kwargs):
**if** request.user.is_authenticated() **and** request.user.points < 10:
logger.warning('The {} user has tried to write a review, but does not have enough points to do so'.format( request.user.pk))
**return** HttpResponseForbidden()
**return** func(request, *args, **kwargs)
**return** wrapper django.http **import** HttpResponseForbidden
logger = logging.getLogger(__name__)