当前位置: 首页 > news >正文

Django中在CBV(基于类的视图)中添加装饰器

Django的视图分为FBV(基于函数的视图)和CBV(基于类的视图)两种实现方法。FBV比较简单,但是缺点在于很难通过继承等方式重复利用已有代码;CBV使用起来略微繁琐一些,但是却很容易通过类继承等方法重复利用已有代码。当然,FBV如果通过一些方法把内部功能抽取出来做成单独的外部函数也是可以实现重复利用的,只不过CBV的继承更加直观。

Python装饰器用于函数的时候是很方便的,类中的方法与独立函数略有不同,所以用于FBV的装饰器不能直接用在CBV上,所以说用于类就不太方便。当Django使用CBV时,装饰器的使用就要比FBV繁琐一些。

大体上分为3种方法:

对CBV类的某一个方法加装饰器

Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器

from django.views import View
from django.utils.decorators import method_decorator
from lib.decorator import my_decorator

class AddClass(View):

    @method_decorator(my_decorator)
    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")

比如说开发者在lib.decorator中自己开发了一个装饰器my_decorator,就可以通过

@method_decorator(my_decorator)

把这个my_decorator加到CBV类内特定的函数上。比如说上面的例子就是加载了get函数上,这样当访问者通过GET方法访问到这个AddClass时,就会调用这个装饰器。

在dispatch方法加装饰器

在CBV的各个方法中,有一个比较特殊的方法dispatch,这个方法执行的时间比get、post等函数更早,所以可以添加一些对request.method无关的装饰器

class AddClass(View):

	 def get(self,request, year):
	 	print('this is add method')
	 	return return render(request, "add_class.html")

	 @method_decorator(my_decorator)
	 def dispatch(self, request, *args, **kwargs):
	 	print('this is dispatch method')
	 	return None

要特别说明的是:Django自带的各个_required方法都无法加在get、post等方法上,而是必须要加在dispatch方法上。另外csrf_exempt和csrf_protect这两个装饰器也只能加在dispatch方法上。

给CBV类加装饰器

通过method_decorator可以给类加装饰器,在添加的时候只要增加一个name参数就可以指定该装饰器是对CBV内哪个方法来添加

@method_decorator(my_decorator_post, name='post')
@method_decorator(my_decorator_get, name='get') 
class AddClass(View):

    def get(self, request):
        return render(request, "add_class.html")

    def post(self, request):
        class_name = request.POST.get("class_name")
        models.Classes.objects.create(name=class_name)
        return redirect("/class_list/")

在路由中加装饰器

https://stackoverflow.com/questions/6069070/how-to-use-permission-required-decorators-on-django-class-based-views

对如何在CBV上加装饰器有一些讨论,其中提到,其实可以在路由文件urls.py中加装饰器。

from django.urls import path
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from . import views

app_name = 'rbac'  # pylint: disable=invalid-name
urlpatterns = [
    path(r'Login/', csrf_exempt(views.LoginView.as_view()), name='Login'),
    path(r'Logout/', login_required(views.LogoutView.as_view()), name='Logout'),
]

 这种方法的效果和在dispatch方法上加装饰器是一样的,代码可以少很多;不过缺点就是在试图稳健views.py中看不出来,有可能会导致误解,如果urls.py和view.py是两个不同的人编写的,可能会冲突。

相关文章:

  • 【笑小枫的SpringBoot系列】【十】SpringBoot处理请求跨域问题
  • 算法竞赛入门【码蹄集进阶塔335题】(MT2326-2330)
  • Keychron Q1:客制化机械键盘|体验
  • Linux C/C++ 多线程开发 - 基础介绍
  • C语言内存讲解-详说内存分布和heap空间
  • SpringBoot电商项目前后端界面搭建
  • Android 天气APP(三十六)运行到本地AS、更新项目版本依赖、去掉ButterKnife
  • 【C++学习】string的使用
  • WeMos Mini ESP32-S2FN4R2介绍
  • Halcon图像分割总结
  • 5 h0255. 迷宫问题,6 h0253. 鸣人和佐助(广度优先搜索)
  • 《数据结构》堆栈(铁路、洗牌、汉诺塔、走迷宫)全解析
  • 基于时序行为的协同过滤推荐算法(Python)
  • Vue--》计算属性与监视(侦听)属性的使用
  • 【状语从句练习题】because / because of / although / in spite of
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • Java反射-动态类加载和重新加载
  • js 实现textarea输入字数提示
  • js如何打印object对象
  • node和express搭建代理服务器(源码)
  • Python连接Oracle
  • Spring声明式事务管理之一:五大属性分析
  • Swoft 源码剖析 - 代码自动更新机制
  • Terraform入门 - 1. 安装Terraform
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • Xmanager 远程桌面 CentOS 7
  • 多线程 start 和 run 方法到底有什么区别?
  • 给新手的新浪微博 SDK 集成教程【一】
  • 离散点最小(凸)包围边界查找
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端工程化(Gulp、Webpack)-webpack
  • 思考 CSS 架构
  • 算法-图和图算法
  • 小李飞刀:SQL题目刷起来!
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 自制字幕遮挡器
  • 白色的风信子
  • 组复制官方翻译九、Group Replication Technical Details
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • # Panda3d 碰撞检测系统介绍
  • #QT项目实战(天气预报)
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (三)elasticsearch 源码之启动流程分析
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 中让 Task 支持带超时的异步等待
  • .NET使用存储过程实现对数据库的增删改查
  • .NET中统一的存储过程调用方法(收藏)
  • // an array of int
  • @ModelAttribute 注解
  • []Telit UC864E 拨号上网
  • [2009][note]构成理想导体超材料的有源THz欺骗表面等离子激元开关——