Pour le boulot, je devais réaliser un prototype implémentant des processus simples, c'est-à-dire représentés par une suite d'étapes ordonnées. On peut facilement se représenter un tel processus en considérant une ligne de métro avec ses stations sans ramifications.
C'est relativement simple à énoncer mais c'est un peu plus difficile à modéliser, commençons par le modèle de données appliqué à Django (simplifié):
class Step(models.Model):
title = models.CharField()
class Process(models.Model):
title = models.CharField()
class ProcessWorkflow(models.Model):
source = models.ForeignKey(Step)
target = models.ForeignKey(Step)
process = models.ForeignKey(Process)
On dispose donc maintenant d'étapes et de processus. La classe/table ProcessWorkflow permet de lier les étapes entre elles au sein d'un processus.
Une fois ce modèle créé, il s'agit de reconstruire le workflow lorsqu'on en a besoin. Pour cela, un fonction récursive permet assez élégamment de se sortir d'affaire. C'est peut-être ici qu'il peut y avoir mieux en termes de performance mais dans le cadre de mon prototype c'est suffisant:
def build_linear_workflow(items, steps=None, source=None):
""" Recursive function to build a linear workflow, return a step list. """
if steps is None:
steps = []
for item in items:
if item.source == source:
if item.target is None:
return steps
else:
steps.append(item.target)
return build_linear_workflow(items, steps, item.target)
La fonction est relativement générique car elle me permet de former des workflows d'étapes, de processus, de projets, etc. Je pense qu'elle est relativement facile à comprendre avec le nom des variables choisies (le problème de performance est au niveau de la boucle sur l'ensemble des items, je pense que je pourrais facilement retirer l'item ajouté à steps).
Il ne reste plus qu'à ajouter cette ressource sous la forme d'un propriété au précédent modèle, la classe Process devient alors:
class Process(models.Model):
title = models.CharField()
def get_workflow(self):
return build_linear_workflow(ProcessWorkflow.objects.filter(process=self.id))
workflow = property(get_workflow)
On peut maintenant utiliser directement le workflow dans un template de la façon suivante:
<h3>{{ process.title }}</h3>
{% if process.workflow %}
<ul>
{% for step in process.workflow %}
<li>{{ step.title }}</li>
{% endfor %}
</ul>
{% endif %}
Simple comme Django :-).
Voici le fruit de mes recherches, merci à tous ceux qui ont contribué au résultat final, n'hésitez pas à réagir si vous avez une solution plus simple/élégante. La prochaine étape, c'est de passer aux workflows plus complexes, pouvant présenter des arborescences ascendantes et/ou descendantes. Le casse-tête ne fait que commencer...
J'ai mis ça sous trac: opensvn.csie.org/traccgi/...
J'ai repris le nom openflow, je dois pas avoir le droit mais bon ...
Le projet openflow contient 3 applis:
- workflow: implémentation style openflow
- leave: vide, destiné à recevoir une le clone de leave/openflow
- test: appli de test basique avec utilisation du framework test django 0.96
Tiens je ne connaissais pas, très intéressant !
Pour l'instant la seule implémentation que j'ai trouvé en python est celle de CPS développée par Nuxeo : www.cps-project.org/secti...
Je vais creuser de ce côté là, merci.
J'ai l'impression que les projets de workflow en python un peu sérieux sont pas légions, surtout depuis que Zope est passé en v3; Les produits sous Zope v2 ne sont pas migrés, et Nuxeo abandonne python pour Java.
Il y avait pourtant un projet, openflow, qui m'a l'air intéressant:
www.openflow.it/
Ce serait à mon avis intéressant de le "retranscrire" sous Django; si ça intéresse qqun, j'ai commencé à modéliser quelques models ...
avec quel langega on peux réaliser ça, et quels sont ls outils necessaire pour créer un exemple d'un workflow.
Merci pour cet exemple clair. Si j'ai bien compris, à partir d'un process, on peut modéliser une arborescence d'étapes à réaliser que l'on peut récupérer sous la forme d'une liste simple.
D'où cette question : Peut gérer des structures arborescentes comme des listes imbriquées avec Django ? C'est une chose que je n'ai encore jamais vue. Le langage de template ne semble pas offrir cette fonctionnalité par défaut.
Salut,
Très intéressant ton article, mais qu'entends-tu par processus? et comment utilises-tu ces processus dans ton context?
Vous n'avez pas de bibliothèque pour XPDL en Python ?
Oh, très intéressant, je veux bien voir ce que ça peut donner !
Pour l'instant j'ai commencé une implémentation from scratch car nos besoins sont très spécifiques mais je me suis grandement inspiré des workflows à activités comme openflow ou le module wfmc de Zope svn.zope.org/zope.wfmc/tr...
Quoi qu'il en soit, mon adresse est sur la page de contact ;-).
@Olivier : des échantillons doivent suivre des suites d'étapes définies par les utilisateurs (expériences). Grâce à cette implémentation des workflows, je peux facilement représenter à l'écran ces suites d'étapes.
@Batiste : bien sûr, dans l'exemple donné, si step possède un workflow lui aussi (concept de sous-étape), il suffit de faire une boucle sur step.workflow, et ainsi de suite avec une profondeur (quasi) infinie.