zoukankan      html  css  js  c++  java
  • Python装饰器、Django自定义登录验证

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

    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}) #用户名渲染到前端页面
    
  • 相关阅读:
    springmvc入门&参数&注解
    springmvc_ssm Spring、SpringMVC、MyBatis集成
    spring-dbutils&注解
    如何快速进去 注册表
    数据库的导出 与导入 速度相当快的方法
    常见的问题:https://localhost:1158/em 无法打开
    卸载windows服务
    用语句创建 表空间、临时表空间、用户 等规则
    游标 根据目录号 操作用户 查看 对应得影像数
    根据 目录号 案卷号 用户名 查询 page 中 的条数
  • 原文地址:https://www.cnblogs.com/honey-badger/p/8978168.html
Copyright © 2011-2022 走看看