Как создать процесс Django ViewFlow программно

справка

Я разрабатываю веб-приложение для изучения Django (python 3.4 & Django 1.6.10). Веб-приложение имеет сложные и часто обновляемые рабочие процессы. Я решил интегрировать библиотеку Django-Viewflow (https://github.com/viewflow/viewflow/), поскольку это очень удобный способ обработки рабочих процессов и не включать логику рабочего процесса с моделями приложений.

в этом случае, я создал рабочий процесс, чтобы собрать информация об авторстве и авторские права с помощью библиотеки Django-Viewflow. Рабочий процесс должен инициироваться каждый раз, когда автор добавляется в Книгу.

Моя Проблема

документация предлагает пошаговые рекомендации по интеграции сквозного решения worklfow (frontend и backend). Моя проблема в том, что мне трудно программно управлять рабочим процессом (в частности, из модели книги).

описание применение

у меня есть модель книги (основная модель) с отношением многих ко многим авторам.

myApp/models.py

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

компоненты рабочего процесса:

myFlow/models.py

from viewflow.models import Process

class AuthorInvitation(process)     
    consent_confirmed = models.BooleanField(default=False)
    signature = models.CharField(max_length=150) 

myFlow/flows.py

from viewflow import flow
from viewflow.base import this, Flow
from viewflow.contrib import celery
from viewflow.views import StartProcessView, ProcessView
from . import models, tasks

class AuthorInvitationFlow(Flow):
    process_cls = models.AuthorInvitation

    start = flow.Start(StartProcessView) 
        .Permission(auto_create=True) 
        .Next(this.notify)

    notify = celery.Job(tasks.send_authorship_request) 
        .Next(this.approve)

    approve = flow.View(ProcessView, fields=["confirmed","signature"]) 
        .Permission(auto_create=True) 
        .Next(this.check_approve)

    check_approve = flow.If(cond=lambda p: p.confirmed) 
        .OnTrue(this.send) 
        .OnFalse(this.end)

    send = celery.Job(tasks.send_authorship) 
        .Next(this.end)

    end = flow.End()

вопрос

как вы можете управлять процессом рабочего процесса программно (активировать, подтвердить шаги, повторить шаги, отменить процесс....)? Я пытался покопаться в коде библиотеки. Кажется, что class activate содержится правильный метод, но не уверен, как все должно быть организовано.

спасибо заранее!

2 ответов


для потоков доступны две дополнительные задачи Start build-in

StartFunction-запускает поток, когда функция вызывается где-то:

@flow_start_func
def create_flow(activation, **kwargs):
    activation.prepare()
    activation.done()
    return activation

class FunctionFlow(Flow):
    start = flow.StartFunction(create_flow) \
        .Next(this.end)

# somewhere in the code
FunctionFlow.start.run(**some_kwargs)

StartSignal-запускает поток на прием сигнала django:

class SignalFlow(Flow):
    start = flow.StartSignal(some_signal, create_flow) \      
        .Next(this.end)

вы можете проверить использование для них, а остальная часть встроенной задачи в этот набор тестов viewflow.

для ручной обработки состояния задачи сначала вы должны получить задачу из базы данных, активировать ее и вызвать любой способ активации.

task  = MyFlow.task_cls.objects.get(...)
activation = task.activate()
if  activation.undo.can_proceed():
    activation.undo()

любой переход активации .can_proceed() метод, помогает вам проверить, является задачей в состоянии, которое позволяет переход.


мне нужно было вручную или программно запустить экземпляр потока. Модель, с которой я закончил, основана на приведенной выше ссылке на StartFunction выглядит так:

class MyRunFlow(flow.Flow):
    process_class = Run

    start = flow.Start(ProcessCreate, fields=['schedule']). \
        Permission(auto_create=True). \
        Next(this.wait_data_collect_start)
    start2 = flow.StartFunction(process_create). \
        Next(this.wait_data_collect_start)

обратите внимание, что важным моментом является то, что process_create имеет Process объект и этот код должны программно настроить те же поля, что и ручная отправка формы через спецификацию полей в ProcessCreate:

@flow_start_func
def process_create(activation: FuncActivation, **kwargs):
    #
    # Update the database record.
    #
    db_sch = Schedule.objects.get(id=kwargs['schedule'])
    activation.process.schedule = db_sch # <<<< Same fields as ProcessCreate
    activation.process.save()
    #
    # Go!
    #
    activation.prepare()
    activation.done()
    return activation

отметим, что activation подкласс внутри flow_start_func и FuncActivation, который имеет методы prepare() и save (). The kwargs приходят из вызова для запуска, который идет что-то вроде:

start_node = <walk the flow class looking for nodes of type StartFunction>
activation = start_node.run(schedule=self.id)