12π
There are two additional Start build-in Tasks available for Flows
StartFunction β starts flow when the function called somewhere:
@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 β starts flow on django signal receive:
class SignalFlow(Flow):
start = flow.StartSignal(some_signal, create_flow) \
.Next(this.end)
You can check the usage for them, and rest of build-in task in this viewflow test suite.
For manually process the task state, first you should get the task from the database, activate it, and call any activation method.
task = MyFlow.task_cls.objects.get(...)
activation = task.activate()
if activation.undo.can_proceed():
activation.undo()
Any activation transition have .can_proceed()
method, helps you to check, is the task in the state that allows the transition.
1π
I needed to be able to manually or programmatically start a flow instance. The model I ended up with, based on the above reference to StartFunction
looks like this:
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)
Note the important point is that process_create
has the Process
object and this code must programmatically set up the same fields that the manual form submission does via the fields specification to 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
Note that the activation
subclass inside the flow_start_func
is FuncActivation
, which has the prepare() and save() methods. The kwargs
come from the call to run, which goes something like:
start_node = <walk the flow class looking for nodes of type StartFunction>
activation = start_node.run(schedule=self.id)
0π
to start manually:
from viewflow import flow
from viewflow.base import this, Flow
from .models import CIE
from viewflow import frontend
from django.utils.decorators import method_decorator
@frontend.register
class CIE(Flow):
process_class = CIE
start = flow.StartFunction(this.create_flow).Next(this.end)
end = flow.End()
@method_decorator(flow.flow_start_func)
def create_flow(self, activation):
activation.prepare()
activation.done()
return activation
after that expose rpc:
from modernrpc.core import rpc_method
from flow.flows import CIE
@rpc_method
def start():
CIE.start.run()
- Django forms give: Select a valid choice. That choice is not one of the available choices
- Django testing how to assert Redirect
- Django Views: When is request.data a dict vs a QueryDict?