装饰器作用

decorator是当今最流行的设计模式之一,很多使用它的人并不知道它是一种设计模式。这种模式有什么特别之处? 有兴趣可以看看Python Wiki上例子,使用它可以很方便地修改对象行为,通过使用类似例中的接口将修改动作封装在装饰对象中。

decorator 可以动态地修改函数、方法或类的功能,而无需创建子类或修改类的源代码。正因为如此,装饰器可以让代码将变得更干净更可读更可维护(这很重要!),并且减少了许多冗余但又不得不写的代码,使我们可以使用单个方法向多个类添加功能。

对于装饰器的重用性和易用性,Django里面的@login_required就是一个很好的例子。使用它只用一句代码就可以检查用户是否通过身份验证,并将未登录用户重定向到登录url。

该装饰器的使用方法如下:

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
...

每次用户试图访问 my_view 时,都会进入 login_required 中的代码。

Django装饰器

下面介绍一些个人认为比较有用的,或者是之前使用过的具有积极效果的装饰器。事先声明,如要实现同样的业务场景,并不是只有本文中的方法。Django可以实现各种各样的装饰器,这完全根据您的需要进行定制。

Group Required

有时需要保护一些视图,只允许某些用户组访问。这时就可以使用下面的装饰器来检查用户是否属于该用户组。

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):
...

有关此装饰器更多的介绍,可以参考这里

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):
...

有关此装饰器更多的介绍,可以参考这里

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):
...

有关此装饰器更多的介绍,可以参考这里

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):
...

有关此装饰器更多的介绍,可以参考这里

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):
...

有关此装饰器更多的介绍,可以参考这里

自定义功能

下面这个装饰器只是一个示例,测试你能够轻松地检查某些权限或某些判断条件,并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中六个常用的自定义装饰器的更多相关文章

  1. 详解Django中六个常用的自定义装饰器

    装饰器作用 decorator是当今最流行的设计模式之一,很多使用它的人并不知道它是一种设计模式.这种模式有什么特别之处? 有兴趣可以看看Python Wiki上例子,使用它可以很方便地修改对象行为, ...

  2. cookie,session 的概念以及在django中的用法,以及cbv装饰器用法

    cookie的由来: 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后 ...

  3. Django学习笔记第八篇--实战练习四--为你的视图函数自定义装饰器

    零.背景: 对于登录后面所有视图函数,都需要验证登录信息,一般而言就是验证cookie里面的一些信息.所以你可以这么写函数: def personinfo(request): ": retu ...

  4. django class类即视图类添加装饰器的几种方法

    根据别人发布整理,个人爱好收集(原文:https://blog.csdn.net/mydistance/article/details/83958655 ) 第一种:定义函数装饰器,在函数,类中使用函 ...

  5. python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器

    1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...

  6. 13、python中的函数(闭包与装饰器)

    一.嵌套函数 函数的内部又再定义另一个函数,这个函数就叫嵌套函数,里面含函数就叫内部函数. 示例: 二.返回函数 函数可以接收函数对象作为参数,同理函数也能返回一个函数对象作为返回值. 示例: 返回函 ...

  7. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  8. python django 自定义 装饰器

    # -*-coding:utf-8-*- __author__ = "GILANG (pleasurelong@foxmail.com)" """ d ...

  9. Django中ORM模板常用属性讲解

    学习了ORM模板中常用的字段以及使用方法,具体如下: from django.db import models # Create your models here. # 如果要将一个普通的类映射到数据 ...

随机推荐

  1. springmvc+mybatis 处理时间

    项目结构: 一.数据库中time的字段为datetime1. 数据库设计如图 2. addNews.jsp <%@ page language="java" contentT ...

  2. 小菜菜mysql练习50题解析——数据准备

    附上数据准备: 学生表 create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10)); ...

  3. 知乎回答:每日完成任务用于打卡的APP

    其实我也一直在寻找最佳的解决方案.安卓上有这样的,叫做HabitHub.用过一段时间,不容易坚持,这个软件对于培养习惯来说无疑是最好的,但是仅限于记录,这样的软件实在太多.我这里提供一下我自己的方法, ...

  4. bzoj3203【sdoi2013】保护出题人

    题目描述 输入格式 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + 1行为Ai和 Xi,分别表示相比上一关在僵尸队列排头增加血量为Ai  ...

  5. 配置iOS项目的设备系统目标设置:Base SDK和Deployment Target

    配置iOS项目的设备系统目标设置:Base SDK和Deployment Target Xcode为开发者提供了两个可配置的设置:第一个是Base SDK,第二个是iOS的Deployment Tar ...

  6. [poj 1533]最长上升子序列nlogn树状数组

    题目链接:http://poj.org/problem?id=2533 其实这个题的数据范围n^2都可以过,只是为了练习一下nlogn的写法. 最长上升子序列的nlogn写法有两种,一种是变形的dp, ...

  7. R画图

    画图函数中的参数: 1.图形元素参数: pch:用于显示点的坐标,可以是一个字符,也可以是0到25的一个整数.如:pch=“+”,pch=1 lty:线条类型.如:lty=2,lty=1 lwd:线条 ...

  8. 003 Python与类C语言的区别(未完)

    #写在前面的话:重点记录Python的特点 Python特点: 1. 无分号断句 2. 不用担心溢出问题 3. if-else的用法不同 #if或else后面都要添加冒号: import random ...

  9. centos禁用ipv6

    两步完成 vi /etc/sysctl.conf net.ipv6.conf.all.disable_ipv6=1sysctl -p /etc/sysctl.conf

  10. Docker集群管理Swarm数据持久化

    一.前言 和docker容器一样,Swarm集群中运行的服务也能够做数据持久化.我们可以通过volume.bind和nfs等方式来实现swarm集群应用数据的持久化.其实和docker数据持久化的形式 ...