Django 的工作流程框架

发布于 2024-11-25 13:36:13 字数 1539 浏览 0 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

百合的盛世恋 2024-12-02 13:36:13

让我在这里给出一些注释,因为我是 django-fsm 和 django-viewflow 的作者,这两个项目可以称为“工作流库”。

工作流程这个词本身有点被高估了。不同类型的库和软件可以称自己为“工作流”,但具有不同的功能。
共同点是工作流将某些流程的步骤连接成一个整体。

一般分类

据我所知,工作流实现方法可以分为以下几类:

  • 单/多用户 - 工作流库是否自动执行单用户任务或具有权限检查/任务分配选项。
  • 顺序/并行 - 顺序工作流程只是一种状态机模式实现,允许同时具有单个活动状态。并行工作流程允许同时执行多个活动任务,并且可能具有某种并行同步/连接功能。
  • 显式/隐式 - 无论工作流是表示为单独的外部实体,还是编织到其他类中,主要职责都是不同的。
  • 静态/动态 - 静态工作流程在Python代码中实现一次然后执行,动态工作流程通常可以通过更改工作流程数据库表的内容来配置。静态工作流程通常可以更好地与 django 基础设施的其余部分集成
    像视图、表单和模板,并支持通过常用的 Python 结构(如类继承)进行更好的自定义。动态工作流假设您具有可以适应任何工作流运行时更改的通用接口。

其中,前两个可以被认为是渐进的差异,但其他两个是根本性的。

具体包

这里是我们现在 django、djangopackages 和 awesome-django 项目的简要描述工作流程部分下的列表

  • django.contrib.WizardView - 隐式、单用户、顺序、静态我们可以拥有的最简单的工作流程实现。它将中间状态存储在隐藏表单发布数据中。
  • django-flows - 显式、单用户、顺序、静态工作流程,将流程状态保留在外部存储中,以允许用户关闭或打开另一个选项卡上的页面并继续工作。
  • django-fsm - 隐式、多用户、顺序、静态工作流程- 最紧凑、最轻量的状态机库。状态更改事件表示为模型类的 python 方法调用。对流继承和覆盖有基本支持。提供用于将权限与状态转换相关联的插槽。允许使用乐观锁定来防止并发状态更新。
  • django-states - 显式、多用户、顺序、静态具有用于状态机和状态转换的单独类的工作流。通过将转换的字符串名称传递给 make_transition 方法来进行转换。提供将权限与状态转换关联起来的方法。有一个简单的 REST 通用端点,用于使用 AJAX 调用更改模型状态。状态
    文档中没有提到机器继承支持,但类状态定义使得无需或很少修改核心库即可实现机器继承支持。
  • django_xworkflows - 没有支持的显式、顺序、静态工作流程用于用户权限检查,状态机的分离类。使用元组进行状态和转换定义,使工作流继承支持变得困难。
  • django-workflows - 显式、多用户、顺序、动态工作流程将状态存储在库提供的 django 模型中。有一种方法可以将权限附加到工作流转换,基本上就是这样。

这些django状态机库都不支持并行工作流程,这很大程度上限制了它们的应用范围。但有两个可以做到:

  • django-viewflow - 显式、多用户、并行、静态工作流程,支持并行任务执行、复杂的拆分和连接语义。提供帮助程序与 django 功能和基于类的视图集成,以及不同的后台任务执行查询,以及各种悲观和乐观锁定策略以防止并发更新。

  • 问题中提到的

    GoFlow往往是显式、多用户、并行、动态工作流程,但它已被作者放弃多年。

我看到了在 django-viewflow 之上实现动态工作流构建功能的方法。一旦完成,它将结束 django 世界中最后一个也是最复杂的工作流实现案例。

希望,如果有人能够阅读到目前为止,现在可以更好地理解工作流术语,并且可以为他们的项目有意识地选择工作流库。

Let me give a few notes here as i'm the author of django-fsm and django-viewflow, two projects that could be called "workflow libraries".

Workflow word itself is a bit overrated. Different kind of libraries and software could call themselves "workflow" but have varying functionality.
The commonality is that a workflow connects the steps of some process into a whole.

General classification

As I see, workflow implementation approaches can be classified as follows:

  • Single/Multiple users - Whether workflow library automates single user tasks or has permission checking/task assignment options.
  • Sequential/Parallel - Sequential workflow is just a state machine pattern implementation and allows to have single active state at a moment. Parallel workflows allow to have several active tasks at once, and probably have some sort of parallel sync/join functionality.
  • Explicit/Implicit - Whether workflow is represented as a separate external entity, or is weaved into some other class, that main responsibility is different.
  • Static/Dynamic - Static workflows are implemented in python code once and then executed, dynamic workflows typically could be configuring by changing contents of workflow database tables. Static workflows are usually better integrated with the rest of the django infrastructure
    like views, forms and templates, and support better customization by usual python constructions like class inheritance. Dynamic workflows assume that you have generic interface that can adapt to any workflow runtime changes.

Of these, the first two could be considered gradual differences, but the other two are fundamental.

Specific packages

Here is brief description what we have nowadays in django, djangopackages and awesome-django project list under workflow section:

  • django.contrib.WizardView - implicit, single user, sequential, static the simplest workflow implementation we could have. It stores intermediate state in the hidden form post data.
  • django-flows - explicit, single user, sequential, static workflow, that keeps flow state in external storage, to allow user to close or open page on another tab and continue working.
  • django-fsm - implicit, multi-user, sequential, static workflow - the most compact and lightweight state machine library. State change events represented just as python methods calls of model class. Has rudimentary support for flow inheritance and overrides. Provides slots for associate permission with state transitions. Allows to use optimistic locking to prevent concurrent state updates.
  • django-states - explicit, multi-user, sequential, static workflow with separate class for state machine and state transitions. Transitions made by passing string name of transition to make_transition method. Provides way for associate permission with state transitions. Has a simple REST generic endpoint for changing model states using AJAX calls. State
    machine inheritance support is not mentioned in the documentation, but class state definition makes it possible with none or few core library modifications.
  • django_xworkflows - explicit, sequential, static workflow with no support for user permission checking, separated class for state machine. Uses tuples for state and transition definitions, makes workflow inheritance support hard.
  • django-workflows - explicit, multi-user, sequential, dynamic workflow storing the state in library provided django models. Has a way to attach permission to workflow transition, and basically thats all.

None of these django state machine libraries have support for parallel workflows, which limits their scope of application a lot. But there are two that do:

  • django-viewflow - explicit, multi-user, parallel, static workflow, with support for parallel tasks execution, complex split and join semantic. Provides helpers to integrate with django functional and class based views, and different background task execution queries, and various pessimistic and optimistic lock strategies to prevent concurrent updates.

  • GoFlow, mentioned in question, tends to be the explicit, multi-user, parallel, dynamic workflow, but it has been forsaken by author for a years.

I see the way to implement dynamic workflow construction functionality on top of django-viewflow. As soon as it is completed, if will close the last and the most sophisticated case for workflow implementation in the django world.

Hope, if anyone was able to read hitherto, now understands the workflow term better, and can do the conscious choice for workflow library for their project.

饮惑 2024-12-02 13:36:13

是否还有其他值得考虑、可能更好或得到更好支持的选项?

是的。

Python。

您不需要工作流程产品来自动执行状态转换、许可以及审计日志记录和通知等其他功能。

这样做的项目不多是有原因的。

  • 状态设计模式非常容易实现。

  • 授权规则(“许可”)已经是一流的
    Django 的一部分。

  • 日志记录已经是 Python 的一流部分(并且已经
    添加到 Django)。使用它进行审计日志记录要么是审计
    表或另一个记录器(或两者)。

  • 消息框架(“通知”)已经是 Django 的一部分。

您还需要什么?你已经拥有了这一切。

使用 State 设计模式的类定义以及用于授权和日志记录的装饰器效果非常好,您不需要任何超出现有功能的东西。

阅读此相关问题:在 Python 中实现“规则引擎”

Are there other options out there worth considering that might be better or better supported?

Yes.

Python.

You don't need a workflow product to automate the state transitions, permissioning, and perhaps some extras like audit logging and notifications.

There's a reason why there aren't many projects doing this.

  • The State design pattern is pretty easy to implement.

  • The Authorization rules ("permissioning") are already a first-class
    part of Django.

  • Logging is already a first-class part of Python (and has been
    added to Django). Using this for audit logging is either an audit
    table or another logger (or both).

  • The message framework ("notifications") is already part of Django.

What more do you need? You already have it all.

Using class definitions for the State design pattern, and decorators for authorization and logging works out so well that you don't need anything above and beyond what you already have.

Read this related question: Implementing a "rules engine" in Python

霊感 2024-12-02 13:36:13

这很有趣,因为我会同意 S.Lott 的观点,即只使用 Python 作为规则引擎。完成这件事后,我有了完全不同的看法。

如果你想要一个完整的规则引擎,它需要相当多的活动部件。我们构建了一个完整的 Python/Django 规则引擎,您会对需要构建哪些内容才能启动并运行一个出色的规则引擎感到惊讶。我将进一步解释,但首先该网站是 http://nebrios.com

规则引擎至少应具有:

  • 访问控制列表 - 您希望每个人都看到所有内容吗?
  • 键/值对 API - KVP 存储状态,所有规则都会对更改的状态做出反应。
  • 调试模式 - 能够查看每个更改的状态、更改的内容以及更改的原因。派拉蒙。
  • 通过网络表单和电子邮件进行交互 - 能够快速编写网络表单脚本是一个巨大的优势,并且能够一致地解析传入的电子邮件。
  • 流程 ID - 这些跟踪具有业务价值的“线程”。否则流程将不断重叠。
  • 还有更多!

因此,请尝试 Nebri 或我在下面列出的其他产品,看看它们是否满足您的需求。

这是调试模式

在此处输入图像描述

自动生成的表单

在此处输入图像描述

示例工作流规则:

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 构建基于规则、基于事件的工作流引擎并不简单。我们已经做了一年多了!我建议使用诸如

It's funny because I would have agreed with S.Lott about just using Python as is for a rule engine. I have a COMPLETELY different perspective now having done it.

If you want a full rule engine, it needs a quite a few moving parts. We built a full Python/Django rules engine and you would be surprised what needs to be built in to get a great rule engine up and running. I will explain further, but first the website is http://nebrios.com.

A rule engine should atleast have:

  • Acess Control Lists - Do you want everyone seeing everything?
  • Key/Value pair API - KVP's store the state, and all the rules react to changed states.
  • Debug mode - Being able to see every changed state, what changed it and why. Paramount.
  • Interaction through web forms and email - Being able to quickly script a web form is a huge plus, along with parsing incoming emails consistently.
  • Process ID's - These track a "thread" of business value. Otherwise processes would be continually overlapping.
  • Sooo much more!

So try out Nebri, or the others I list below to see if they meet your needs.

Here's the debug mode

enter image description here

An auto generated form

enter image description here

A sample workflow rule:

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}}""")

So, no, it's not simple to build a rules based, event based workflow engine in Python alone. We have been at it over a year! I would recommend using tools like

终止放荡 2024-12-02 13:36:13

我的同事 django-fsm 编写的包似乎有效 - 它是既相当轻量又足够实用。

A package written by an associate of mine, django-fsm, seems to work--it's both fairly lightweight and sufficiently featureful to be useful.

梦幻的心爱 2024-12-02 13:36:13

我可以再添加一个库,该库支持工作流组件的动态更改,这与其等效项不同。

看看 django-river

它现在有一个漂亮的管理员,名为 河流管理

I can add one more library which supports on the fly changes on workflow components unlike its equivalents.

Look at django-river

It is now with a pretty admin called River Admin

榕城若虚 2024-12-02 13:36:13

ActivFlow:一个通用、轻量级且可扩展的工作流引擎,用于复杂业务流程操作的敏捷开发和自动化。

您可以立即建模整个工作流程!

第 1 步:工作流应用注册

WORKFLOW_APPS = ['leave_request']

第 2 步:活动配置

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 步:流程定义

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'

ActivFlow: a generic, light-weight and extensible workflow engine for agile development and automation of complex Business Process operations.

You can have an entire workflow modeled in no time!

Step 1: Workflow App Registration

WORKFLOW_APPS = ['leave_request']

Step 2: Activity 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

Step 3: Flow Definition

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
    }
}

Step 4: Business Rules

def validate_request(self):
    return self.reason == 'Emergency'
缱绻入梦 2024-12-02 13:36:13

我将 django-goflow 从 django 1.X -python 2.X 迁移到适合 django 2.X - python 3.x,该项目位于 django2-goflow

I migrate the django-goflow from django 1.X -python 2.X to fit for django 2.X - python 3.x, the project is at django2-goflow

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文