Django视图函数函数之视图装饰器
FBV模式装饰器:
普通函数的装饰器(语法糖@)
views.py
1 from django.shortcuts import render 2 3 def wrapper(f): 4 def inner(*args,**kwargs): 5 print("before") 6 ret=f(*args,**kwargs) 7 print("after") 8 return ret 9 return inner 10 11 @wrapper 12 def index(request): 13 return render(request,"index.html")
CBV模式装饰器:
在CBV模式视图函数中必须先导入:from django.views import View
(1)重写父类dispatch分发方法,在分发执行每个请求响应函数前后加上相应功能为实现类比装饰器
views.py
1 from django.shortcuts import render,HttpResponse 2 from django.views import View 3 from django.utils.decorators import method_decorator 4 5 class Myview(View): 6 7 def dispatch(self, request, *args, **kwargs): 8 print("before") 9 ret=super().dispatch(request, *args, **kwargs) 10 print("after") 11 return ret 12 13 def get(self, request): 14 return render(request, "login.html") 15 16 def post(self, request): 17 if request.method == "GET": 18 return render(request, "login.html") 19 elif request.method == "POST": 20 if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "123": 21 return render(request, "login_success.html", {"name": request.POST.get("username")}) 22 else: 23 return HttpResponse("账号或密码有误!")
(2)在子类重写分发函数时加上装饰器(每个请求函数都会被装饰)
必须先导入:
from django.views import View
from django.utils.decorators import method_decorator
views.py
1 from django.shortcuts import render,HttpResponse 2 from django.views import View 3 from django.utils.decorators import method_decorator 4 5 def wrapper(f): 6 def inner(*args,**kwargs): 7 print("before") 8 ret=f(*args,**kwargs) 9 print("after") 10 return ret 11 return inner 12 13 class Myview(View): 14 15 @method_decorator(wrapper) 16 def dispatch(self, request, *args, **kwargs): 17 ret=super().dispatch(request, *args, **kwargs) 18 return ret 19 20 def get(self, request): 21 return render(request, "login.html") 22 23 def post(self, request): 24 if request.method == "GET": 25 return render(request, "login.html") 26 elif request.method == "POST": 27 if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "123": 28 return render(request, "login_success.html", {"name": request.POST.get("username")}) 29 else: 30 return HttpResponse("账号或密码有误!")
(3)在子类重写的不同响应请求函数上加上装饰器
必须先导入:
from django.views import View
from django.utils.decorators import method_decorator
views.py
1 from django.shortcuts import render,HttpResponse 2 from django.views import View 3 from django.utils.decorators import method_decorator 4 5 def wrapper(f): 6 def inner(*args,**kwargs): 7 print("before") 8 ret=f(*args,**kwargs) 9 print("after") 10 return ret 11 return inner 12 13 class Myview(View): 14 # def dispatch(self, request, *args, **kwargs): 15 # ret=super().dispatch(request, *args, **kwargs) 16 # return ret 17 18 def get(self, request): 19 return render(request, "login.html") 20 21 @method_decorator(wrapper) 22 def post(self, request): 23 if request.method == "GET": 24 return render(request, "login.html") 25 elif request.method == "POST": 26 if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "123": 27 return render(request, "login_success.html", {"name": request.POST.get("username")}) 28 else: 29 return HttpResponse("账号或密码有误!")
(4)在子类定义时加上装饰器,必须指定而且唯一指定加在的函数
必须先导入:
from django.views import View
from django.utils.decorators import method_decorator
views.py
1 from django.shortcuts import render,HttpResponse 2 from django.views import View 3 from django.utils.decorators import method_decorator 4 5 6 def wrapper(f): 7 def inner(*args,**kwargs): 8 print("before") 9 ret=f(*args,**kwargs) 10 print("after") 11 return ret 12 return inner 13 14 @method_decorator(wrapper,name="post") 15 16 class Myview(View): 17 # def dispatch(self, request, *args, **kwargs): 18 # ret=super().dispatch(request, *args, **kwargs) 19 # return ret 20 21 def get(self, request): 22 return render(request, "login.html") 23 24 def post(self, request): 25 if request.method == "GET": 26 return render(request, "login.html") 27 elif request.method == "POST": 28 if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "123": 29 return render(request, "login_success.html", {"name": request.POST.get("username")}) 30 else: 31 return HttpResponse("账号或密码有误!")
其它装饰器:
· 添加装饰器前必须导入from django.utils.decorators import method_decorator
· 添加装饰器的格式必须为@method_decorator(),括号里面为装饰器的函数名
· 给类添加是必须声明name
· 注意csrf-token装饰器的特殊性,在CBV模式下它只能加在dispatch上面(后面再说)
下面这是csrf_token的装饰器:
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置csrfToken全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注意:from django.views.decorators.csrf import csrf_exempt,csrf_protect