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 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 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())