xadmin的插件机制
xadmin的视图方法中如果加了@filter_hook 标记的都可以作为插件的钩子函数。
例如在ListAdminView类中有许多加了上述标记的方法,
@filter_hook
def get_context(self):
"""
Prepare the context for templates.
"""
self.title = _('%s List') % force_unicode(self.opts.verbose_name) model_fields = [(f, f.name in self.list_display, self.get_check_field_url(f))
for f in (self.opts.fields + self.get_model_method_fields()) if f.name not in self.list_exclude] new_context = {
'module_name': force_unicode(self.opts.verbose_name_plural),
'title': self.title,
'cl': self,
'model_fields': model_fields,
'clean_select_field_url': self.get_query_string(remove=[COL_LIST_VAR]),
'has_add_permission': self.has_add_permission(),
'app_label': self.app_label,
'brand_name': self.opts.verbose_name_plural,
'brand_icon': self.get_model_icon(self.model),
'add_url': self.model_admin_url('add'),
'result_headers': self.result_headers(),
'results': self.results()
}
context = super(ListAdminView, self).get_context()
context.update(new_context)
return context @filter_hook
def get_response(self, context, *args, **kwargs):
pass
在上述代码中,get_context方法被作为了一个插件钩子函数,当调用该方法的时候,会遍历ListAdminView注册的插件寻找插件中与get_context同名的方法,并把get_context
执行后的结果作为第二个参数(第一个参数是self)传给插件的get_context方法,于是我们可以在get_context方法返回结果前对其结果进行一些修改。正是因为如此,插件的同名方法会比视图的方法多一个参数(用于接收上一个方法传来的返回值)。但这不是绝对的。如果被hook的方法没有返回值则插件方法可以不用多设一个参数。
例如,我们想给ListAdminView传给模板的context中增加一个变量(var),我们可以这样定义一个插件:
以下是插件机制实现的原理,其实就是wrap 目标方法,在装饰器中遍历插件形成针对目标方法的插件方法列表,然后在目标方法执行后递归执行。
注意:比较巧妙的是,func if fargs[1] == '__' else func(),也就是说可以根据参数名来决定是把上一结果传过来还是把上一方法传过来,如果是把上一方法传过来
则可以控制方法的执行顺序,可以在上一方法执行前做点改动。
def filter_chain(filters, token, func, *args, **kwargs):
if token == -1:
return func()
else:
def _inner_method():
fm = filters[token]
fargs = getargspec(fm)[0]
if len(fargs) == 1:
# Only self arg
result = func()
if result is None:
return fm()
else:
raise IncorrectPluginArg(u'Plugin filter method need a arg to receive parent method result.')
else:
return fm(func if fargs[1] == '__' else func(), *args, **kwargs)
return filter_chain(filters, token - 1, _inner_method, *args, **kwargs) def filter_hook(func):
tag = func.__name__
func.__doc__ = "``filter_hook``\n\n" + (func.__doc__ or "") @functools.wraps(func)
def method(self, *args, **kwargs): def _inner_method():
return func(self, *args, **kwargs) if self.plugins:
filters = [(getattr(getattr(p, tag), 'priority', 10), getattr(p, tag))
for p in self.plugins if callable(getattr(p, tag, None))]
filters = [f for p, f in sorted(filters, key=lambda x:x[0])]
return filter_chain(filters, len(filters) - 1, _inner_method, *args, **kwargs)
else:
return _inner_method()
return method
xadmin的插件机制的更多相关文章
- 【学】jQuery的源码思路6——增加each,animaion,ajax以及插件机制
each() 插件机制 animation ajax //each() //这里第一个参数指定将this指向每次循环到的那个元素身上,而第三个参数element其实就是this本身所以和第一个参数是一 ...
- ImitateLogin新增插件机制以及又一个社交网站的支持
我的文章里已经多次介绍 imitate-login ,这是我最近一直在维护的一个使用c#模拟社交网站登录的开源项目,现在新增了对插件的支持以及一个新的网站(由于某种原因,会在文章结束部分介绍:而且仅会 ...
- Maven生命周期和插件机制
Maven中的一个非常重要的概念是生命周期和插件,这篇文章重点介绍下Maven的生命周期. Maven的生命周期是抽象的,具体的功能是有具体的插件来完成的,Maven有相当多的功能插件,以至于Mave ...
- php中的钩子(hook插件机制)
对"钩子"这个概念其实不熟悉,最近看到一个php框架中用到这种机制来扩展项目,所以大概来了解下. hook插件机制的基本思想: 在项目代码中,你认为要扩展(暂时不扩展)的地方放置一 ...
- winform插件机制学习
这两天在看自定义控件,原来有太多知识没有掌握.今天看到插件机制,心里突然一亮,这个东西听了不少次,就是不知道是啥回事.这次有幸书里包含一个案例,我就跟着它一步步来.终于知道是什么回事了.这个应该在软件 ...
- [转]仿World Wind构造自己的C#版插件框架——WW插件机制精简改造
很久没自己写东西啦,早该好好总结一下啦!一个大师说过“一个问题不应该被解决两次!”,除了一个好脑筋,再就是要坚持总结. 最近需要搞个系统的插件式框架,我参照World Wind的插件方式构建了个插件框 ...
- WordPress 插件机制的简单用法和原理(Hook 钩子)
WordPress 的插件机制实际上只的就是这个 Hook 了,它中文被翻译成钩子,允许你参与 WordPress 核心的运行,是一个非常棒的东西,下面我们来详细了解一下它. PS:本文只是简单的总结 ...
- 微信开发学习日记(八):7步看懂weiphp插件机制,核心目标是响应微信请求
又经过了几个小时的梳理.回顾,截至目前,终于对weiphp这个框架的机制搞明白了些.想要完全明白,自然还需要大把的时间.第1步: 配置微信公众号,http://weiphp.jiutianniao ...
- typecho流程原理和插件机制浅析(第二弹)
typecho流程原理和插件机制浅析(第二弹) 兜兜 393 2014年04月02日 发布 推荐 1 推荐 收藏 14 收藏,3.7k 浏览 上一次说了 Typecho 大致的流程,今天简单说一下插件 ...
随机推荐
- Linux下源码安装Nginx服务
nginx 安装 linux 系统需要安装必备的开发包,比如 gcc,gcc-c++ 1. openssl (支持 https) https://www.openssl.org/source/ ...
- Material Design之TextInputLayout、Snackbar的使用
这两个控件也是Google在2015 I/O大会上公布的Design Library包下的控件,使用比較简单,就放在一起讲了,但有的地方也是须要特别注意一下. TextInputLayout Text ...
- swift Array 数组
// // main.Swift // swift数组 // // Created by zhangbiao on 14-6-15. // Copyright (c) 2014年 理想. Al ...
- mybatis13 resultMap
resultMap(入门) resultType :指定输出结果的类型(pojo.简单类型.hashmap..),将sql查询结果映射为java对象 . 使用resultType注意:sql查询的列名 ...
- xshell十大技巧
xshell是我用过的最好用的ssh客户端工具,没有之一.这个软件完全免费,简单易用,可以满足通过ssh管理linux vps所有需要,唯一遗憾的是没有官方中文版. 警告:不要下载所谓的汉化版,可能有 ...
- 用java读取properties文件--转
今天为了通过java读取properties文件,google了很长时间,终于找到了.现在特记录之和大家一起分享. 下面直接贴出代码:java类 public class Mytest pub ...
- java Map使用Object 做为Key的问题
近期在看dnsjava 源码的时候,不经意间发现一个自己没有想过的问题: HashMap 如何使用key去查找对应的value的,这个问题很难用语言描述的清楚,那就使用代码来进行说明吧! public ...
- ArcGIS 在地图上添加标注
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Google C++ Style Guide在C++11普及后的变化
转 http://www.cnblogs.com/chen3feng/p/5972967.html?from=timeline&isappinstalled=0&lwfrom=user ...
- TCP/IP 协议理解
TCP/IP 协议(Transmission Control Protocol / internet Protocol),因特网互联协议,又名网络通讯协议.通俗而言:TCP负责发现传输的问题,一有问题 ...