Django视图函数函数之视图装饰器

FBV模式装饰器:

  普通函数的装饰器(语法糖@)

  views.py

 from django.shortcuts import render

 def wrapper(f):
def inner(*args,**kwargs):
print("before")
ret=f(*args,**kwargs)
print("after")
return ret
return inner @wrapper
def index(request):
return render(request,"index.html")

CBV模式装饰器:

    在CBV模式视图函数中必须先导入:from django.views import View

  (1)重写父类dispatch分发方法,在分发执行每个请求响应函数前后加上相应功能为实现类比装饰器

    views.py

 from django.shortcuts import render,HttpResponse
from django.views import View
from django.utils.decorators import method_decorator class Myview(View): def dispatch(self, request, *args, **kwargs):
print("before")
ret=super().dispatch(request, *args, **kwargs)
print("after")
return ret def get(self, request):
return render(request, "login.html") def post(self, request):
if request.method == "GET":
return render(request, "login.html")
elif request.method == "POST":
if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "":
return render(request, "login_success.html", {"name": request.POST.get("username")})
else:
return HttpResponse("账号或密码有误!")

  (2)在子类重写分发函数时加上装饰器(每个请求函数都会被装饰)

必须先导入:

from django.views import View

from django.utils.decorators import method_decorator

       views.py

 from django.shortcuts import render,HttpResponse
from django.views import View
from django.utils.decorators import method_decorator def wrapper(f):
def inner(*args,**kwargs):
print("before")
ret=f(*args,**kwargs)
print("after")
return ret
return inner class Myview(View): @method_decorator(wrapper)
def dispatch(self, request, *args, **kwargs):
ret=super().dispatch(request, *args, **kwargs)
return ret def get(self, request):
return render(request, "login.html") def post(self, request):
if request.method == "GET":
return render(request, "login.html")
elif request.method == "POST":
if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "":
return render(request, "login_success.html", {"name": request.POST.get("username")})
else:
return HttpResponse("账号或密码有误!")

  3)在子类重写的不同响应请求函数上加上装饰器

必须先导入:

from django.views import View

from django.utils.decorators import method_decorator

views.py

 from django.shortcuts import render,HttpResponse
from django.views import View
from django.utils.decorators import method_decorator def wrapper(f):
def inner(*args,**kwargs):
print("before")
ret=f(*args,**kwargs)
print("after")
return ret
return inner class Myview(View):
# def dispatch(self, request, *args, **kwargs):
# ret=super().dispatch(request, *args, **kwargs)
# return ret def get(self, request):
return render(request, "login.html") @method_decorator(wrapper)
def post(self, request):
if request.method == "GET":
return render(request, "login.html")
elif request.method == "POST":
if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "":
return render(request, "login_success.html", {"name": request.POST.get("username")})
else:
return HttpResponse("账号或密码有误!")

  (4)在子类定义时加上装饰器,必须指定而且唯一指定加在的函数

必须先导入:

from django.views import View

from django.utils.decorators import method_decorator

views.py

 from django.shortcuts import render,HttpResponse
from django.views import View
from django.utils.decorators import method_decorator def wrapper(f):
def inner(*args,**kwargs):
print("before")
ret=f(*args,**kwargs)
print("after")
return ret
return inner @method_decorator(wrapper,name="post") class Myview(View):
# def dispatch(self, request, *args, **kwargs):
# ret=super().dispatch(request, *args, **kwargs)
# return ret def get(self, request):
return render(request, "login.html") def post(self, request):
if request.method == "GET":
return render(request, "login.html")
elif request.method == "POST":
if request.POST.get("username") == "yang" and request.POST.get("userpsd") == "":
return render(request, "login_success.html", {"name": request.POST.get("username")})
else:
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

上一篇:js生成一个以零开头的八位数并且依次递增


下一篇:转:AngularJS的Filter用法详解