Django的工作stream框架
我一直在寻找一个框架来简化在Django应用程序中合理复杂的工作stream程的开发。 我想能够使用框架来自动化状态转换,权限,也许还有一些额外的审计日志和通知。
我已经看到了一些关于同一主题的较老的信息,但是在过去的2-3年中并没有太多的信息。 我听说的主要select是GoFlow(自2009年2月以来未更新)和django-workflow(似乎更加活跃)。
有没有人使用这些软件包? 它们是成熟的还是兼容现代的(1.3)Django? 有没有其他的select值得考虑,可能会更好或更好的支持?
让我在这里作一些笔记,因为我是django-fsm和django-viewflow的作者,这两个项目可以称为“工作stream程库”。
工作stream程本身有点被高估。 不同types的库和软件可以称自己为“工作stream”,但具有不同的function。 通用性是一个工作stream将某个过程的步骤连接成一个整体。
一般分类
正如我所看到的,工作stream实施方法可以分类如下:
- 单个/多个用户 – 工作stream程库是否自动执行单个用户任务,还是具有权限检查/任务分配选项。
- 顺序/并行 – 顺序工作stream程仅仅是一个状态机模式的实现,并允许在一个单一的活动状态。 并行工作stream允许同时执行多个活动任务,并且可能具有某种并行同步/连接function。
- 显式/隐式 – 工作stream程是作为一个单独的外部实体表示的,还是被编入其他类中,主要责任是不同的。
- 静态/dynamic – 静态工作stream在Python代码中实现一次,然后执行,dynamic工作stream通常可以通过更改工作stream数据库表的内容进行configuration。 静态工作stream程通常更好地与其他的django基础设施(比如视图,表单和模板)集成在一起,并且通过像inheritance类一样的Python构造来支持更好的定制。 dynamic工作stream假定您具有通用接口,可以适应任何工作stream运行时更改。
其中,前两个可以被认为是渐进的差异,但另外两个是根本的。
具体包
这里简要说明我们现在在django,djangopackages和awesome-django项目列表下的工作stream程部分:
- django.contrib.WizardView – 隐式,单用户,顺序,静态我们可以拥有的最简单的工作stream程实现。 它在隐藏的表单发布数据中存储中间状态。
- django-flows – 显式的单用户顺序静态工作stream程,它保持外部存储中的stream状态,允许用户closures或打开另一个选项卡上的页面并继续工作。
- django-fsm – 隐式,多用户,顺序,静态工作stream程 – 最紧凑,最轻量级的状态机库。 状态改变事件就像模型类的python方法调用一样表示。 对streaminheritance和覆盖有基本的支持。 为关联权限和状态转换提供插槽。 允许使用乐观locking来防止并发状态更新。
- django-states – 显式的,多用户的,顺序的 ,静态的工作stream程,具有独立的状态机和状态转换类。 通过将string名称转换为make_transition方法进行转换。 提供关联权限与状态转换的方式。 有一个简单的REST通用端点,用于使用AJAX调用更改模型状态。 在文档中没有提到状态机inheritance支持,但是类状态定义使得没有或者less数核心库修改成为可能。
- django_xworkflows – 显式,顺序,静态工作stream程,不支持用户权限检查,状态机分离的类。 为状态和转换定义使用元组,使工作streaminheritance支持困难。
- django-workflows – 显式的,多用户的,顺序的,dynamic的工作stream存储库中的状态提供的django模型。 有一种方法来附加权限的工作stream程转换,基本上就是这一切。
这些django状态机库都不支持并行工作stream,这限制了它们的应用范围。 但有两个这样做:
-
django-viewflow – 显式的,多用户的,并行的静态工作stream,支持并行任务执行,复杂拆分和连接语义。 提供帮助与djangofunction和基于类的视图集成,以及不同的后台任务执行查询,以及各种悲观和乐观的locking策略,以防止并发更新。
-
提到的GoFlow往往是一个明确的,多用户的,并行的,dynamic的工作stream程,但它已被作者抛弃了多年。
我看到了在django-viewflow之上实现dynamic工作stream构buildfunction的方法 。 一旦完成,如果将closuresDjango世界中的最后一个和最复杂的工作stream实施案例。
希望如果有人能够阅读到现在,现在可以更好地理解工作stream程术语,并且可以为他们的项目做工作stream程库的有意识的select。
有没有其他的select值得考虑,可能会更好或更好的支持?
是。
python。
您不需要工作stream产品来自动执行状态转换,权限审核以及审核日志logging和通知。
有一个原因,为什么没有太多的项目这样做。
-
国家devise模式很容易实现。
-
授权规则(“授权”)已经是Django的头等部分。
-
日志logging已经是Python的头等部分(并且已经被添加到了Django中)。 用于审计日志logging是审计表或另一个logging器(或两者)。
-
消息框架(“通知”)已经是Django的一部分。
你还需要什么? 你已经拥有了一切。
对状态devise模式使用类定义,对授权和日志logging使用装饰器效果非常好,以至于你不需要超出已有的东西。
阅读这个相关的问题: 在Python中实现一个“规则引擎”
我的一位同事django-fsm编写的软件包似乎可以工作 – 它既轻巧又足够有用。
这很有趣,因为我会同意S.Lott关于像规则引擎一样使用Python。 我现在已经完成了一个完全不同的观点。
如果你想要一个完整的规则引擎,它需要相当多的移动部分。 我们build立了一个完整的Python / Django规则引擎,你会惊奇地发现需要build立和运行一个伟大的规则引擎。 我会进一步解释,但首先网站是http://nebrios.com 。
规则引擎至less应具有:
- 访问控制列表 – 你想让每个人都看到一切吗?
- 键/值对API – KVP的存储状态,所有的规则对变化的状态作出反应。
- debugging模式 – 能够看到每一个改变的状态,改变了它的原因和原因。 派拉蒙。
- 通过网页表单和电子邮件进行交互 – 能够快速编写网页表单是一个巨大的优势,同时还能一致地parsing传入的电子邮件。
- 进程ID – 这些跟踪业务价值的“线索”。 否则,过程将不断重叠。
- 还有更多!
所以试试Nebri,或者我下面列出的其他人,看他们是否满足你的需求。
这是debugging模式
一个自动生成的表单
示例工作stream程规则:
class task_sender(NebriOS): # send a task to the person it got assigned to listens_to = ['created_date'] def check(self): return (self.created_date is not None) and (self.creator_status != "complete") and (self.assigned is not None) def action(self): send_email (self.assigned,""" The ""{{task_title}}"" task was just sent your way! Once you finish, send this email back to log the following in the system: i_am_finished := true It will get assigned back to the task creator to look over. Thank you!! - The Nebbs """, subject="""{{task_title}}""")
所以,不,在Python中单独构build基于规则的基于事件的工作stream引擎并不简单。 我们已经在这一年了! 我会推荐使用类似的工具
我可以添加一个库,它支持在工作stream组件上的变化不同于其等价物。
看django河
ActivFlow :一个通用,轻量且可扩展的工作stream引擎,用于复杂业务stream程操作的敏捷开发和自动化。
您可以立即build立完整的工作stream程!
第1步:工作stream应用程序注册
WORKFLOW_APPS = ['leave_request']
第2步:活动configuration
from activflow.core.models import AbstractActivity, AbstractInitialActivity from activflow.leave_request.validators import validate_initial_cap class RequestInitiation(AbstractInitialActivity): """Leave request details""" employee_name = CharField( "Employee", max_length=200, validators=[validate_initial_cap]) from = DateField("From Date") to = DateField("To Date") reason = TextField("Purpose of Leave", blank=True) def clean(self): """Custom validation logic should go here""" pass class ManagementApproval(AbstractActivity): """Management approval""" approval_status = CharField(verbose_name="Status", max_length=3, choices=( ('APP', 'Approved'), ('REJ', 'Rejected'))) remarks = TextField("Remarks") def clean(self): """Custom validation logic should go here""" pass
第3步:stream程定义
FLOW = { 'initiate_request': { 'name': 'Leave Request Initiation', 'model': RequestInitiation, 'role': 'Submitter', 'transitions': { 'management_approval': validate_request, } }, 'management_approval': { 'name': 'Management Approval', 'model': ManagementApproval, 'role': 'Approver', 'transitions': None } }
第4步:业务规则
def validate_request(self): return self.reason == 'Emergency'