Writing custom views

Viewflow is a workflow library that adds a lightweight workflow layer around Django Views. By doing so, it extracts workflow logic out of views.

When you use Viewflow, it wraps Django views and injects a request.activation instance of the viewflow.workflow.Activation class. Before executing the view code, Viewflow checks the permissions and state of the workflow to ensure that the task can be executed. The view code only needs to run activation.execute() as soon as the task is marked complete and the next tasks need to be activated.

One of the benefits of Viewflow is that a single view can be attached and reused with different Viewflow nodes. The view code should only be responsible for task logic and remain independent from the workflow. This makes it easier to maintain and modify the code over time, without having to make changes to the underlying workflow structure.

Function-based views

Function-based views in Viewflow provide a simple and flexible way to define custom views for workflow tasks. Here’s an example sketch of a custom functional-based view:

def task_view(request, **kwargs):
    form = MyForm(request.POST or None)

    if form.is_valid():
        # Save the form data to the database
        object = form.save(commit=True)

        # Keep it as workflow process artifact
        request.activation.process.artifact = object

        # Execute the workflow task
        request.activation.execute()

        # Redirect to the next avaialbe task
        return redirect(request.activation.get_success_url(request))

    # Render the task form
    return render(request, "task.html", {
        "form": form,
        "activation": request.activation
    })

As you can see, the request.activation.execute() method is called after the form is completed, which triggers the workflow task to be marked as complete and activates the next task in the workflow. The flow_viewset.get_success_url(request) method is used to determine the URL to redirect to after the task is complete.

Class-based views

Class-based views offer a convenient way to create custom views in Viewflow. To integrate a custom view with a workflow, we can simply add self.request.activation.execute() in the form_valid method of the view. We can also use TaskSuccessUrlMixin as a shortcut to determine the redirect location after a task is completed.

from viewflow.workflow.flow.views import mixins

class CustomFormView(mixins.TaskSuccessUrlMixin, generic.CreateView):
    model = SomeModel
    fields = ["acth", "estradiol", "free_t3", "free_t4"]

    def form_valid(self, form):
        object = form.save()
        object.save()

        # Keep it as workflow process artifact
        request.activation.process.artifact = object

        self.request.activation.execute()
        return redirect(self.get_success_url())