如何在CBV中使用装饰器

文章目录

    • 1 装饰器简介
    • 2 CBV的装饰器使用
      • 1 在路由层使用装饰器
      • 2 在视图层中使用装饰器
      • 2.1 同时添加多个装饰器
      • 2.3 在类中的方法上添加装饰器
      • 2.4 直接在类上添加装饰器
        • 2.4.1 单独为类中的函数添加装饰器
        • 2.4.2 为类中的所有函数添加装饰器
    • 3 Django装饰器方法
      • 3.1 自定义函数
      • 3.2 Django内置装饰器简单介绍(常用)
        • 3.2.1 auth模块
          • login_required 方法
          • permission_required 方法
        • 3.2.2 cache 模块
          • cache_page 方法
          • cache_control 方法
          • never_cache方法
        • 3.2.3 http 模块
          • require_http_methods 方法
        • 3.2.4 csrf 模块
          • def csrf_exempt 方法
          • csrf_protect 方法

1 装饰器简介

概念:本质上是一个python闭包函数,可以让其他函数在不需要做任何代码的变动的前提下增加额外的功能;返回值也是函数的对象,

作用:提高代码重复利用率,缩减代码量,同时也有助于代码的可读性和可维护性

应用场景:
1 计算某个函数的运行时间和运行次数(通过在外层函数加上时间计算函数或运算次数统计函数)
2 框架的路由传参()
3 函数的运行日志(插入日志)
4 多个函数实现事务处理的一致性(让函数一起成功运行,或一起运行失败)
5 缓存(实现缓存处理)
6 权限校验(在函数外层套上权限验证的代码,实现权限校验)

2 CBV的装饰器使用

1 在路由层使用装饰器

在视图入口处,即路由分发的过程中使用

通过as_view(),类会被转换成视图函数。在转换好的视图函数上直接使用装饰器函数

from django.contrib.auth.decorators import login_required, permission_required
from django.views.generic import TemplateView
from .views import VoteView

urlpatterns = [
    path('about/', login_required(TemplateView.as_view(template_name="secret.html"))),
    path('vote/', permission_required('polls.can_vote')(VoteView.as_view())),
]

此方法会为该类的所有的方法加上装饰器,而不能为单个方法添加

2 在视图层中使用装饰器

使用 method_decorator 方法将其转换为适用于类视图方法的装饰器

2.1 同时添加多个装饰器

method_decorator方法支持同时添加多个装饰器,先将要用的装饰器放在一个元祖或list中

decorators = [never_cache, login_required]

@method_decorator(decorators, name='dispatch')
class ProtectedView(TemplateView):
    template_name = 'secret.html'

@method_decorator(never_cache, name='dispatch')
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
    template_name = 'secret.html'

2.3 在类中的方法上添加装饰器

不用指定name值,name值默认为空

from django.contrib.auth.decorators import login_required
from django.views import View
from django.utils.decorators import method_decorator

class Order(View):
    @method_decorator(login_required)
    def get(self, request):
        return render(request, 'order.html')

2.4 直接在类上添加装饰器

必须把方法名称作为参数给到name

2.4.1 单独为类中的函数添加装饰器

name属性只支撑一个对象,当需要为多个方法使用同一个装饰器时,需要重复添加

@method_decorator(login_required, name='post')
@method_decorator(login_required, name="get")
class Logout(View):
    def get(self, request):
        auth.logout(request)
        return redirect('/login_c/')
    def post(self, request):
        return redirect('/cheeck/')

2.4.2 为类中的所有函数添加装饰器

将name设为dispatch,dispatch内部通过反射来实现函数执行

@method_decorator(login_required, name="dispatch")
class Logout(View):
    def get(self, request):
        auth.logout(request)
        return redirect('/login_c/')
    def post(self, request):
        return redirect('/cheeck/')

在Django 1.9之前,不能对类使用method_decorator,必须重写dispatch方法;

在Django 1.9版本,有内部定义dispatch方法

Django 1.9 前版本

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

class ProtectedView(TemplateView):
    template_name = 'secret.html'
	
    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

Django 1.9及以后版本

@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
    template_name = 'secret.html'

method_decorator方法会对收到的被装饰对象进行判断:

​ 如果是方法,继续进行装饰;如果是类,需要调取name值作为实际被装饰对象。所以在类中使用时,需要把方法名给name

3 Django装饰器方法

3.1 自定义函数

def login(request):
    if request.method == "GET":
        return render   (request, "login.html")
    else:
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_obj = auth.authenticate(username=username, password=password)
        if user_obj:
            auth.login(request, user_obj)
            path = request.GET.get('next') or '/index/'
            return redirect(path)
        return redirect('/login/')

3.2 Django内置装饰器简单介绍(常用)

3.2.1 auth模块

login_required 方法

登录验证(通过session key检查是否登录),验证通过后可征程执行请求,验证失败后记录当前请求地址并跳转登录页面,在登录成功后跳转已经记录好下来的请求地址
全局设置中后设置登录验证后跳转地址:

LOGIN_URL = '/accounts/login/'

需要在setting中重新定义:

LOGIN_URL = '/login/'
permission_required 方法

权限验证(通过数据库中的auth_permission数据表检查),权限能约束用户行为,当业务逻辑中涉及到权限检查时

3.2.2 cache 模块

cache_page 方法

对页面进行缓存(可在参数中定义过期时间)

cache_control 方法

控制缓存

私有缓存数据(用户浏览器)和公有缓存数据(提供者),需要一个方法告诉缓存那些数据是私有的,那些是可以共享的

never_cache方法

禁用缓存,节省存储空间

3.2.3 http 模块

Django框架在进行路由分发时,不管是FBV还是CBV,完全依赖于用户请求的URL,不考虑请求所使用的HTTP方法。
也就是说,对同一个URL使用不同的HTTP方法,都将由同一个视图函数处理。

require_http_methods 方法

通过这个函数设定只允许的请求方法,从而拦截不允许的请求方法并在拦截后返回405错误,参数为列表形式

基于require_http_methods方法,有三个可直接使用的方法
require_GET() 只支持GET请求
require_POST() 只支持POST请求
require_SAFE() 只支持GET和HEAD请求

3.2.4 csrf 模块

局部设置防跨站请求伪造功能(全局用中间件)

def csrf_exempt 方法

标识一个视图可以被跨域访问,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件

csrf_protect 方法

为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件

你可能感兴趣的:(Django)