web-dev-qa-db-ja.com

Djangoのワークフローフレームワーク

Djangoアプリケーションでの合理的に複雑なワークフローの開発を簡素化するためのフレームワークを探していました。このフレームワークを使用して、状態遷移、許可、およびおそらく監査ログや通知などの追加機能。

同じトピックに関する古い情報をいくつか見ましたが、過去2〜3年はそれほど多くありません。私が聞いた主な選択肢は、GoFlow(2009年2月以降更新されていない)とDjango-workflow(よりアクティブに思われる)です。

誰かがこれらのパッケージを使用しましたか?成熟しているか、最新の(1.3)Djangoと互換性がありますか?より良いまたはよりよくサポートされているかもしれないと考える価値がある他のオプションはありますか?

44

ここで、私がDjango-fsmとDjango-viewflowの作成者である2つのプロジェクトを「ワークフローライブラリ」と呼ぶことができるので、いくつか注意しておきます。

ワークフローワード自体は少し過大評価されています。さまざまな種類のライブラリとソフトウェアは、それ自体を「ワークフロー」と呼ぶことができますが、機能はさまざまです。共通点は、ワークフローが一部のプロセスのステップを全体に接続することです。

一般的分類

私が見るように、ワークフロー実装アプローチは次のように分類できます。

  • Single/Multiple users-ワークフローライブラリがシングルユーザータスクを自動化するか、権限チェック/タスク割り当てオプションを持つか。
  • Sequential/Parallel-シーケンシャルワークフローは、単なるステートマシンパターンの実装であり、一度に1つのアクティブな状態にすることができます。並列ワークフローでは、一度にいくつかのアクティブなタスクを実行でき、おそらく何らかの並列同期/結合機能があります。
  • Explicit/Implicit-ワークフローが個別の外部エンティティとして表されるか、他のクラスに組み込まれるかにかかわらず、その主な責任は異なります。
  • Static/Dynamic-静的ワークフローはpythonコードで一度実装されてから実行され、通常、ワークフローデータベーステーブルの内容を変更することで動的ワークフローを構成できます。通常、静的ワークフローは、ビュー、フォーム、テンプレートなどのDjangoインフラストラクチャとよりよく統合されており、クラスの継承などの通常のpython構造によるより良いカスタマイズをサポートしています。動的ワークフローは、ワークフローのランタイムの変更に適応できる汎用インターフェースがあることを前提としています。

これらのうち、最初の2つは段階的な違いと考えることができますが、残りの2つは基本的なものです。

特定のパッケージ

以下は、現在のDjango、djangopackages、および awesome-Djangoプロジェクトリスト のワークフローセクションでの簡単な説明です。

  • Django.contrib.WizardView -暗黙的、単一ユーザー、シーケンシャル、静的可能な最も単純なワークフロー実装。中間状態を非表示フォームの投稿データに保存します。
  • Django-flows -explicit、single user、順次、staticワークフロー、外部ストレージにフローの状態を保持し、ユーザーがページを閉じたり開いたりできるようにします別のタブで作業を続けます。
  • Django-fsm -暗黙、マルチユーザー、シーケンシャル、静的ワークフロー-最もコンパクトで軽量なステートマシンライブラリ。状態変更イベントは、モデルクラスのpythonメソッド呼び出しとして表されます。フローの継承とオーバーライドの基本的なサポートがあります。権限を状態遷移に関連付けるためのスロットを提供します。楽観的ロックを使用して、状態の同時更新を防ぐことができます。
  • Django-states -explicit、multi-user、順次、状態マシンと状態遷移のための個別のクラスを持つ静的ワークフロー。トランジションの文字列名をmake_transitionメソッドに渡すことによって行われるトランジション。権限を状態遷移に関連付ける方法を提供します。 REST呼び出しを使用してモデルの状態を変更するための単純なAJAX汎用エンドポイントがあります。ステートマシンの継承のサポートはドキュメントに記載されていませんが、クラスステートの定義により、コアライブラリの変更をまったくまたはほとんど行わなくても可能になります。
  • Django_xworkflows -explicit、シーケンシャル、静的ユーザー権限チェックのサポートのないワークフロー、ステートマシンの分離されたクラス。状態と遷移の定義にタプルを使用し、ワークフローの継承サポートを困難にします。
  • Django-workflows -explicit、multi-user、順次、dynamic提供されるライブラリに状態を保存するワークフローDjangoモデル。ワークフローの移行に権限を付与する方法があり、基本的にそれですべてです。

これらのDjangoステートマシンライブラリは、並列ワークフローをサポートしていないため、アプリケーションのスコープが大幅に制限されます。ただし、次の2つがあります。

  • Django-viewflow -explicit、multi-user、parallel、staticワークフロー、並列タスクの実行、複雑な分割と結合のセマンティクスをサポート。 Djangoの機能ベースおよびクラスベースのビュー、さまざまなバックグラウンドタスク実行クエリ、さまざまな悲観的および楽観的ロック戦略と統合して、同時更新を防ぐヘルパーを提供します。

  • GoFlowは、問題となっているexplicit、multi-user、parallel、dynamicワークフローになる傾向がありますが、作成者によって何年も見捨てられてきました。

Django-viewflow の上に動的ワークフロー構築機能を実装する方法がわかります。それが完了するとすぐに、ifはDjangoの世界でのワークフロー実装の最後の最も洗練されたケースを閉じます。

誰かがこれまで読むことができたなら、ワークフローの用語をよりよく理解し、プロジェクトのワークフローライブラリを意識して選択できることを願っています。

88
kmmbvnr

より良いまたはよりよくサポートされているかもしれないと考える価値がある他のオプションはありますか?

はい。

Python。

状態遷移、許可、および監査ログや通知などの追加機能を自動化するワークフロー製品は必要ありません。

これを行うプロジェクトが少ないのには理由があります。

  • Stateデザインパターンの実装は非常に簡単です。

  • 認可ルール(「許可」)はすでにDjangoの第一級の部分です。

  • ロギングはすでにPython(およびDjangoに追加されました)のファーストクラスの部分です。これを監査ロギングに使用することは、監査テーブルまたは別のロガー(あるいはその両方)です。

  • メッセージフレームワーク(「通知」)はすでにDjangoの一部です。

さらに何が必要ですか?あなたはすでにそれをすべて持っています。

State設計パターンのクラス定義を使用し、承認とロギングにデコレーターを使用するとうまく機能するため、これまで以上に何も必要ありません持ってる。

この関連質問を読んでください: Pythonでの「ルールエンジン」の実装

8
S.Lott

Pythonをそのままルールエンジンとして使用することについてS.Lottに同意したので、それはおかしいです。今では完全に異なる視点を持っています。

完全なルールエンジンが必要な場合は、かなりの数の可動部品が必要です。私たちは完全なPython/Djangoルールエンジンを構築しました。優れたルールエンジンを稼働させるために何を組み込む必要があるかは驚くでしょう。さらに説明しますが、最初のウェブサイトは http://nebrios.com です。

ルールエンジンには少なくとも次のものが必要です。

  • アクセスコントロールリスト-全員にすべてを表示しますか?
  • Key/ValueペアAPI-KVPは状態を保存し、すべてのルールは変更された状態に反応します。
  • デバッグモード-変更されたすべての状態、変更された状態、および理由を確認できます。パラマウント。
  • Webフォームと電子メールによる相互作用-Webフォームをすばやくスクリプト化できることは、着信電子メールを一貫して解析することに加えて、大きなプラスです。
  • プロセスID-これらはビジネス価値の「スレッド」を追跡します。そうしないと、プロセスが継続的に重複します。
  • すごい!

だから、Nebriや下に挙げた他のものを試してみて、それらがあなたのニーズを満たしているかどうか確かめてください。

これがデバッグモードです

enter image description here

自動生成されたフォーム

enter image description here

ワークフロールールの例:

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=だけで構築するのは簡単ではありません。1年以上かかっています!次のようなツールの使用をお勧めします

5
Adam

私の仲間が書いたパッケージ Django-fsm は機能しているようです-かなり軽量であり、有用であるために十分な機能を備えています。

5

同等のものとは異なり、ワークフローコンポーネントのオンザフライの変更をサポートするライブラリをもう1つ追加できます。

Django-river を見てください

River Admin というかなりの管理者がいます。

4
Ahmet DAL

Django-goflowをDjango 1.X -python 2.XからDjango 2.X-python 3.xに合うように移行しました。プロジェクトはat Django2-goflow

1
mikewolfli

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'
1
faxad