Modélisation d'un workflow linéaire avec Django

Tags associés : , , , posté le 23 march 2007


Logo associé au billet intitulé Modélisation d'un workflow linéaire avec Django

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

9 Commentaires

Salut,

Très intéressant ton article, mais qu'entends-tu par processus? et comment utilises-tu ces processus dans ton context?

1 | Olivier, le 24 March 2007 à 11h

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.

2 | Batiste, le 24 March 2007 à 12h

@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.

3 | David, biologeek, le 24 March 2007 à 13h

Vous n'avez pas de bibliothèque pour XPDL en Python ?

4 | Damien B, le 27 March 2007 à 14h

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.

5 | David, biologeek, le 28 March 2007 à 11h

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

6 | Miloz, le 17 July 2007 à 20h

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 ;-).

7 | David, biologeek, le 17 July 2007 à 21h

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

8 | Miloz, le 18 July 2007 à 22h

avec quel langega on peux réaliser ça, et quels sont ls outils necessaire pour créer un exemple d'un workflow.

9 | foufou, le 9 September 2008 à 11h

Ajouter un commentaire


Billets contextuels

Sortie de Django 1.0, une année de nouveautés

Logo associé au billet intitulé Sortie de Django 1.0, une année de nouveautés

J'étais assez sceptique lors de l'annonce de la roadmap avant l'été mais il faut bien avouer que ça n'a pas chômé pendant ces vacances et que les développeurs sont arrivés à bout des fonctionnalités annoncées. Chapeau ...

Des vacances et des liens

Logo associé au billet intitulé Des vacances et des liens

Après être venu à bout du 1000+ de Google Reader, autant partager avec vous mes dernières découvertes car les billets de qualité ont été nombreux au cours de mes vacances. J'ai un peu la flemme de tout classer, au ...

Une solution pour faciliter la conception d'applications web RESTful avec Django

Logo associé au billet intitulé Une solution pour faciliter la conception d'applications web RESTful avec Django

Voila la solution à laquelle je suis arrivé après avoir testé les solutions existantes : django collection, django crudapi et django restful model views. J'attends beaucoup du GSoC consacré à l'inclusion native de REST dans Django et les choses ...


© 2004-2008 David Larlet - Licence (presque) libre - Site enfin propulsé par Django et hébergé par Typhon.