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

Posted 笑得好美

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 

 

        

 

以上是关于Django视图函数函数之视图装饰器的主要内容,如果未能解决你的问题,请参考以下文章

Django基础三之视图函数

72Django 之 中间件

装饰器不在 Django 中处理视图函数

Django中基于类的视图上带有参数的函数装饰器

11.Django基础九之中间件

Django 自定义装饰器 - 函数没有属性 get