Search code examples
django-viewflow

How to connect two flows in django-viewflow


I'm using django-viewflow to track complicated business processes. In order to avoid having long Flow classes and flows.py files, I'd like to have one flow feed into another. Is this possible?

I've tried the following code, but Python throws a NotImplemented Exception.

class SecondFlow(Flow):
    process_class = SecondProcess
    start = (...)

class FirstFlow(Flow):
    process_class = FirstProcess
    start = (
        flow.Start(
            CreateProcessView,
            fields=['foo']
        ).Next(SecondFlow.start)
    )

It would be great if FirstFlow routed to the beginning of SecondFlow.

Edit: I tried using the advice and documentation provided, but I'm getting the following error: 'StartFunction' object has no attribute 'prepare'

Below is my new code.

from viewflow import flow, frontend
from viewflow.base import this, Flow
from viewflow.flow.views import CreateProcessView, UpdateProcessView

from .models import FirstProcess, SecondProcess

@frontend.register
class SecondFlow(Flow):
    process_class = SecondProcess
    start = flow.StartFunction(this.create_flow
            ).Next(this.enter_text)

    def create_flow(self, activation, **kwargs):
        activation.prepare()
        activation.done()

    enter_text = (
        flow.View(
            UpdateProcessView,
            fields=['text']
        ).Next(this.end)
    )

    end = flow.End()


@frontend.register
class FirstFlow(Flow):
    process_class = FirstProcess

    start = (
        flow.Start(
            CreateProcessView,
            fields=['text']
        ).Next(this.initiate_second_flow)
    )

    initiate_second_flow = (
        flow.Handler(this.start_second_flow
        ).Next(this.end)
    )

    def start_second_flow(self, activation):
        SecondFlow.start.run()

    end = flow.End()

Second edit: It works after I added a decorator to the create_flow method of SecondFlow.

from django.utils.decorators import method_decorator
...

@frontend.register
class SecondFlow(Flow):
    process_class = SecondProcess
    start = flow.StartFunction(this.create_flow
            ).Next(this.enter_text)

    @method_decorator(flow.flow_start_func)
    def create_flow(self, activation, **kwargs):
        activation.prepare()
        activation.done()

...

Solution

  • flow.Start is the task for a Start view that invoked by a user and creates a process. View could have some logic, and usually, that logic relays on a request data. So you can't invoke flow.StartView and flow.View elsewhere except by accessing an URL form a browser.

    To activate some process programmatically there is the flow.StartFunction - http://docs.viewflow.io/viewflow_core_node.html#viewflow.nodes.StartFunction

    And to execute it from the other flow, flow.Handler could be used - http://docs.viewflow.io/viewflow_core_node.html#viewflow.nodes.Handler