在 Django 中,假设有几个 view, 他们都接受类似的参数,做类似的处理,最后又输出类似的变量到模板中配合显示,唯一不同的就是模板路径。

最普通的写法可能是这样:

def view_a(request, some_id):
    some_obj = SomeClass.objects.get(pk=some_id)
    # 一些处理
    # 
    return render_to_response("a.html", {'some_obj': some_obj},
        context_instance=RequestContext(request))

def view_b(request, some_id):
    some_obj = SomeClass.objects.get(pk=some_id)
    # 一些处理
    # 
    return render_to_response("b.html", {'some_obj': some_obj},
        context_instance=RequestContext(request))

def view_c(request, some_id):
    some_obj = SomeClass.objects.get(pk=some_id)
    # 一些处理
    # 
    return render_to_response("c.html", {'some_obj': some_obj},
        context_instance=RequestContext(request))

这里显然很多代码重复,最容易想到的是把同样的代码取出来放到一个函数里,重构后代码变成了这样:

def some_logic(request, some_id, template_path):
    some_obj = SomeClass.objects.get(pk=some_id)
    # 一些处理
    # 
    return render_to_response(template_path, {'some_obj': some_obj},
        context_instance=RequestContext(request))

def view_a(request, some_id):
    some_logic(request, some_id, "a.html")

def view_b(request, some_id):
    some_logic(request, some_id, "b.html")

def view_c(request, some_id):
    some_logic(request, some_id, "c.html")

好多了,可是我们注意到传递进 view 的一些参数(这里只有一个 some_id)仍然重复的写了很多次。有没有更好的办法呢?有的,用 function decorator,可以写成这样:

def foo_view(template_path):
    def my_decorator(f):
        def new_f(request, some_id, *args, **kwds):
            some_obj = SomeClass.objects.get(pk=some_id)
            # 一些处理
            # 
            return render_to_response(template_path, {'some_obj': some_obj},
                context_instance=RequestContext(request))
        new_f.func_name = f.func_name
        return new_f
    return my_decorator
            
@foo_view("a.html")
def view_a(request, some_id):
    pass

@foo_view("b.html")
def view_b(request, some_id):
    pass

@foo_view("c.html")    
def view_c(request, some_id):
    pass

这样具体的 view 里面什么代码也没写,仅仅向 decorator 传递了一个模板名称的参数就搞定了。具体的实现,被封装到了 foo_view 这个 decorator 的内部函数里面。decorator 的作用看上去类似于 C# 的 Attribute, 但实际上强大很多,Attribute 仅仅相当于一个简单的元数据,具体实现还需要在其他类里面去分离实现,并且查找理解起来也不太方便,尤其在阅读大型类库的时候。而 python 里的 decorator 可以对函数做任意的修改,可任意添加前置(pre),后置(post) 操作,甚至完全取代掉原来的函数。可以辅助做参数、返回值类型检测、AOP (用的比较多的有日志、异常处理等)等功能,十分强大和灵活。

在 Django 的 View 中利用 function decorator 可实现一定程度的代码重用相关推荐

  1. html 中箭头的代码,HTML中利用div+CSS实现简单的箭头图标的代码

    /*箭头向上*/ .to_top { width: 0; height: 0; border-bottom: 10px solid #ccc; border-left: 10px solid tran ...

  2. html直线箭头,HTML中利用div+CSS实现简单的箭头图标的代码

    在网页设计中,我们经常得会用到一些箭头做为装饰来点缀我们的网页,虽然现在很多的网站的设计者们都喜欢以引用字体图标的形式来实现箭头的效果,但那样也会给网页的加载造成一些影响.今天飞鸟慕鱼小编就给大家说一 ...

  3. Django在view中读取txt文件

    问题描述: 在view中想加载一个block-words的txt来屏蔽脏字. 但是一直报错找不到文件 解决方法: 使用完整路径,把txt放在view.py同一路径下,加入前两行即可 module_di ...

  4. django的view中或者前台中动态的添加属性

    1.view中动态的添加属性,到时候这个queryset集合就有了添加的属性,前台就可以获取数据了 news_info = NewsInfo.objects.all() for new_info in ...

  5. matlab中利用function定义复数运算

    定义一个函数,在进行运算

  6. 【Vue3 造轮子项目 】kaiteUI中利用Custom Block(自定义块)和vite实现代码渲染器

    关于kaiteUI中通过json数据实现代码渲染器 前言 上礼拜笔者分享了搭建UI框架的技术栈,其中一个较为关键的技术--代码渲染器,由于篇幅问题放到了今天这篇博客中给大家做一个详细的分析解读. 在这 ...

  7. android开发 app消息提醒功能,Android中利用App实现消息推送机制的代码

    1.消息推送机制 服务器器端需要变被动为主动,通知客户一些开发商认为重要的信息,无论应用程序是否正在运行或者关闭. 我想到了一句话:don't call me,i will call you! qq今 ...

  8. django批量修改table_python中Django视图(view)的详解(附示例)

    本篇文章给大家带来的内容是关于python中Django视图(view)的详解(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一个视图函数(类),简称视图,是一个简单的Py ...

  9. android view gesturedetector,如何在Android中利用 GestureDetector进行手势检测

    如何在Android中利用 GestureDetector进行手势检测 发布时间:2020-11-26 16:15:21 来源:亿速云 阅读:92 作者:Leah 今天就跟大家聊聊有关如何在Andro ...

最新文章

  1. 基于生成式深度学习方法设计潜在2019-nCoV蛋白酶抑制剂
  2. Python整型数与字符串相互转换
  3. kernel并发控制:自旋锁、互斥体、中断屏蔽
  4. 嵌入式C语言基础链表
  5. Apache Camel Intellij IDEA插件的工作已开始
  6. (五)官方Neo4j 3.3.9 Java API例子
  7. mysql 123456_MySQL字符串中抽取数值的方法 select -(-'123456@163.com'); 很牛逼
  8. 开放科学背景下的科学数据开放共享:国家青藏高原科学数据中心的实践
  9. C++ STL string的构造函数
  10. Mybatis入门(一)
  11. Kafka : WARN Error while fetching metadata with correlation id xx : {=UNKNOWN_TOPIC_OR_PARTITION}
  12. 我的世界Java版最诡异的种子_我的世界:MC出现诡异的种子,地域不停地重复
  13. c语言从入门到精通真垃圾,从入门到精通的C语言(吐血量)
  14. miscrosoft visio 2003记
  15. 【材料课堂】锂电池基础
  16. 面经自己汇总(三维视觉算法机器学习深度学习)——持续更新
  17. 程序员如何获取招聘信息
  18. Google Voice 语音搜索
  19. (Python)卫星RPC有理多项式模型读取与正反投影坐标计算原理与实现
  20. 喵的Unity游戏开发之路 - 推球:游戏中的物理

热门文章

  1. left join 和 left outer join 的区别
  2. ubuntu14.04 升级gcc的方法
  3. 高频数据交换下Flutter与ReactNative的对比
  4. 生活总是在推着你一步一步往前走
  5. 容器网络Calico进阶实践 | 褚向阳
  6. SQLServer On Linux Package List on CentOS
  7. iOS动画详解(学习动画看这一篇就够了)
  8. CentOS7.2中NFS1.3 安装
  9. silverlight、wpf中 dispatcher和timer区别
  10. 【EXLIBRIS】随笔记 011