python笔记(三十六):xadmin快速搭建后台 (中)

本文详细介绍了Xadmin插件系统的工作原理,包括插件类的创建、注册、初始化、以及如何通过filter_hook装饰器修改或增强AdminView的行为。还涉及了如何在模板中插入自定义内容的方法。
摘要由CSDN通过智能技术生成

Xadmin 插件制作

插件原理

Xadmin 的插件系统架构设计一定程度上借鉴了 wordpress 的设计。 想要了解 Xadmin 的插件系统架构首先需要了解 Xadmin AdminView 的概念。简单来说,就是 Xadmin 系统中每一个页面都是一个 AdminView 对象返回的 HttpResponse 结果。|xadmin| 的插件系统做的事情其实就是在 AdminView运行过程中改变其执行的逻辑, 或是改变其返回的结果,起到修改或增强原有功能的效果。下面让我们看看整个插件从制作完成到实际运行的整个过程。

首先需要创建自己的插件类, 插件类继承 BaseAdminPlugin

class HelloWorldPlugin(BaseAdminPlugin): …

开发好的插件首先要注册到 Xadmin 中, 示例代码如下:

ListAdminView 是 Model 列表页面 xadmin.site.register_plugin(HelloWorldPlugin, ListAdminView)

其中插件的注册和使用可以参看 xadmin.sites.AdminSite.register_plugin()

当将插件注册到 Xadmin 后, Xadmin 在创建 AdminView 实例的时候会将该插件放入实例的 plugins 属性。当 AdminView在处理请求时,会首先逐个调用 plugins 中插件的 init_request() 方法,插件在该方法中一般进行初始化的操作并且返回一个 Boolean 值告诉 AdminView是否需要加载该插件。当 init_request() 方法返回值为 False 时, AdminView 不会加载该插件。实例如下:

class HelloWorldPlugin(BaseAdminPlugin):

say_hello = False # 初始化方法根据 say_hello 属性值返回

def init_request(self, *args, **kwargs):

return bool(self.say_hello)

在以上实例中,插件根据自身的 say_hello 属性来决定是否让自己被加载。您可能会迷惑, say_hello 属性看起来一直会是 False 呀,那样这个插件不是永远不会被加载?其实 Xadmin 在创建插件实例的时候会将 OptionClass 的同名属性替换插件的属性。这样,在不同的 OptionClass 下会有不同的插件结果,实例如下:

class SomeModelAdmin(object):

say_hello = True

… site.register(SomeModel, SomeModelAdmin)

理解以上内容后,让我们再看看插件具体是如何起作用的。在 AdminView 的执行过程中,可以被插件截获或修改的方法使用 filter_hook() 装饰,实例如下:

class ListAdminView(ModelAdminView): # 可以被插件截获或修改的方法使用该装饰器装饰 @filter_hook def get_context(self): …

使用 filter_hook() 装饰的方法执行过程中会根据一定原则执行插件中的同名方法,具体信息查考该装饰器的文档内容。

xadmin.views.base.filter_hook(func)[source]

表明 AdminView 的方法可以被插件插入的装饰器。执行使用了该装饰器的方法时,会按照以下过程执行:

  1. 首先将实例的 plugins 属性取出,取出含有同样方法名的插件

  2. 按照插件方法的 priority 属性排序

  3. 顺序执行插件方法,执行插件方法的规则:

  • 如果插件方法没有参数,AdminView 方法的返回结果不为空则抛出异常

  • 如果插件方法的第一个参数为 __ ,则 AdminView 方法将作为第一个参数传入,注意,这时还未执行该方法,在插件中可以通过 __() 执行,这样就可以实现插件在 AdminView 方法执行前实现一些自己的逻辑,例如:

def get_context(self, ): c = {‘key’: ‘value’} c.update(()) return c

* 如果插件方法的第一个参数不为 __ ,则执行 AdminView 方法,将结果作为第一个参数传入
  1. 最终将插件顺序执行的结果返回

根据该装饰器的执行原则,如果我们想修改上面示例中 ListAdminView 的 get_context 的返回值,可以在插件中实现如下代码:

class HelloWorldPlugin(BaseAdminPlugin):

在插件中加入同名方法,修改 ListAdminViewget_context 返回的值

def get_context(self, context):

context.update({‘hello_target’: ‘World!!’})

return context

如果我们希望插件在 AdminView 的方法前执行,或是完全使用自己的方法替代 AdminView 的方法可以这样:

class HelloWorldPlugin(BaseAdminPlugin):

第一个参数为 __ 。这样 __ 即为 ListAdminViewget_context 方法本身,注意,这时还没有执行这个方法。

#我们可以在任何时候执行 AdminView 的方法,或是根本不执行 #context.update(__())

def get_context(self, __):

context = {‘hello_target’: ‘World!!’}

return context

至此,加入的插件就实现了对 AdminView 方法的完全控制。

模板插件

我们知道,Django 中一个完整的 View 是包含模板的,模板用来生成 View 最终返回的 HTML 内容。当然,插件也可以在模板中插入自己的内容。我们来看看具体如何实现。

首先让我们来看看 Xadmin 中的模板代码示例片段 (change_list.html):

{% load xadmin %} …

其中的 view_block Tag 即为插件的 插入点 。插件可以在自己的插件类中使用 block_ + 插入点名称 方法将 HTML 片段插入到页面的这个位置,示例如下:

class HelloWorldPlugin(BaseAdminPlugin):

context 即为 TemplateContext, nodes 参数包含了其他插件的返回内容。

您可以直接返回 HTML 片段,或是将内容加入到 nodes 参数中

def block_results_top(self, context, nodes):

return s"

Hello %s
" % context[‘hello_target’]

转自:https://www.cnblogs.com/Miracle-boy/articles/9968686.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值