Python裝飾器、Django自定義登陸驗證

裝飾器是一個很著名的設計模式,常常被用於有切面需求的場景,較爲經典的有插入日誌、性能測試、事務處理等。
裝飾器其實就是一個工廠函數,它接受一個函數爲參數,而後返回一個新函數,其閉包中包含了原函數html

一、簡單裝飾器:前端

def deco(func):
    def wrapper():
        print "start"
        func() #調用函數
        print "end"
    return wrapper

@deco
def myfun():
    print "run"

myfun()

因爲裝飾器函數返回的是原函數的閉包wrapper,實際上被裝飾後的函數就是wrapper,其運行方式就和wrapper同樣。至關於:
myfun=deco(myfun)python

二、裝飾任意參數的函數:django

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

 三、帶參數的裝飾器設計模式

裝飾器接受一個函數做爲參數,這個毋庸置疑。可是有時候咱們須要裝飾器接受另外的參數。此時須要再加一層函數,其實是定義了一個生成裝飾器的工廠函數,調用它,搭配須要的參數,來返回合適的裝飾器session

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)閉包

四、裝飾器帶類參數app

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()

 五、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}) #用戶名渲染到前端頁面
相關文章
相關標籤/搜索