欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python装饰器、Django自定义登录验证

程序员文章站 2022-07-15 08:17:23
...

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。
装饰器其实就是一个工厂函数,它接受一个函数为参数,然后返回一个新函数,其闭包中包含了原函数

1、简单装饰器:

def deco(func):
    def wrapper():
        print "start"
        func() #调用函数
        print "end"
    return wrapper

@deco
def myfun():
    print "run"

myfun()

由于装饰器函数返回的是原函数的闭包wrapper,实际上被装饰后的函数就是wrapper,其运行方式就和wrapper一样。相当于:
myfun=deco(myfun)

2、装饰任意参数的函数:

def deco(func):
    def warpper(*args,**kw):
        print "start"
        func(*args,**kw)
        print "end"
    return warpper
	
@deco
def myfun1(param1):
    print "run with param %s"%(param1)
	
@deco
def myfun2(param1,param2):
    print "run with param %s and %s"%(param1,param2)
	
myfun1("something")
myfun2("something","otherthing")

# start
# run with param something
# end
# start
# run with param something and otherthing
# end

 3、带参数的装饰器

装饰器接受一个函数作为参数,这个毋庸置疑。但是有时候我们需要装饰器接受另外的参数。此时需要再加一层函数,实际上是定义了一个生成装饰器的工厂函数,调用它,搭配需要的参数,来返回合适的装饰器

def log(text):
    def deco(func):
        def wrapper(*args,**kw):
            print text
            func(*args,**kw)
            print text + " again"
        return wrapper
    return deco
	
@log("hello")
def myfun(message):
    print message
	
myfun("world")

# hello
# world
# hello again

log=log("hello"),把返回的deco函数赋值给log,此时log相当于其包含text=“hello”的闭包
myfun=log(myfun),相当于把myfun传入了deco函数,并且返回wrapper,并赋值给myfun,此时myfun相当于其装饰后的闭包。
整体来看是myfun=log("hello")(myfun)

4、装饰器带类参数

class locker:  
    def __init__(self):  
        print("locker.__init__() should be not called.")
	
	@staticmethod  
    def acquire():  
        print("locker.acquire() called.(这是静态方法)")
		
	@staticmethod  
    def release():  
        print("  locker.release() called.(不需要对象实例)")
		
def deco(cls):  
    '''''cls 必须实现acquire和release静态方法'''
	def _deco(func):  
        def __deco(): 
			print("before %s called [%s]." % (func.__name__, cls))  
            cls.acquire()  
            try:  
                return func()  
            finally:  
                cls.release()
		return __deco  
    return _deco
	
@deco(locker)  
def myfunc():  
    print(" myfunc() called.")
	
myfunc()  
myfunc()

 5、django自定义装饰器实现登录验证

def Check_Login(func):  #自定义登录验证装饰器
    def warpper(request,*args,**kwargs):
        is_login = request.session.get('IS_LOGIN', False)
        if is_login:
            func(request,*args,**kwargs)
        else:
            return HttpResponseRedirect("/polls/login_user")
    return warpper

def login_user(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            all_data = form.clean()   #获取post数据,例如 {'username': u'yang1', 'password': 111}
            exist = User.objects.filter(username = all_data['Form_username'],password = all_data['Form_password']).first()
            if exist:
                request.session['IS_LOGIN'] = True  #设置session的随机字段值
                request.session['uname'] = exist.username   #设置uname字段为登录用户
                return HttpResponseRedirect('/polls/home')
            else:
                return HttpResponse("账户或密码错误")
    else:
        form = LoginForm()
    return render(request, 'polls/login_user.html', {'form': form})

@Check_Login
def home(request):
        username = request.session.get('uname', False)   #获取登录用户名
        return render(request, 'polls/home.html', {'username': username}) #用户名渲染到前端页面