Как создать процесс 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)