Viewflow
The low-code for developers with yesterday's deadline
[![build]][build] [![coverage]][coverage] [![pypi-version]][pypi] [![py-versions]][pypi]
Viewflow is a low-code library for building business applications with Django. It gives you ready-made components for user management, workflows, and reporting. You write less code but keep full control. You can customize everything and connect it to your existing systems.
Build full-featured business applications in a few lines of code. Viewflow ships as one package with everything included. Each part works on its own, but they all work well together.
GPT assisted with Viewflow documentation: [Viewflow Pair Programming Buddy][gpt]
Viewflow comes in two versions:
- Viewflow Core: Open-source library with base classes. Build your own solution on top.
- Viewflow PRO: Full package with ready-to-use features and third-party integrations. Commercial license allows private forks and modifications.

Features
- Modern, responsive interface with SPA-style navigation
- Reusable workflow library for BPMN processes
- Built-in CRUD for complex forms and data
- Reporting dashboard included
- Small, easy-to-learn API
Installation
Viewflow works with Python 3.10+ and Django 4.2+
Viewflow:
pip install django-viewflow
Viewflow PRO:
pip install django-viewflow-pro --extra-index-url https://pypi.viewflow.io//simple/
Add to INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
....
'viewflow',
'viewflow.workflow', # if you need workflows
]
Quick start
Here is a pizza ordering workflow example. Full runnable source: demo/helloworld.
1. Create a model for process data
Viewflow provides a Process base model. Use jsonstore fields to store data without extra database joins:
from viewflow import jsonstore
from viewflow.workflow.models import Process
class PizzaOrder(Process):
customer_name = jsonstore.CharField(max_length=250)
address = jsonstore.TextField()
toppings = jsonstore.TextField()
tips_received = jsonstore.IntegerField(default=0)
baking_time = jsonstore.IntegerField(default=10)
class Meta:
proxy = True
2. Create flows.py with your workflow
Define a flow class with steps. Use CreateProcessView and UpdateProcessView for the forms:
from viewflow import this
from viewflow.workflow import flow
from viewflow.workflow.flow.views import CreateProcessView, UpdateProcessView
from .models import PizzaOrder
class PizzaFlow(flow.Flow):
process_class = PizzaOrder
start = flow.Start(
CreateProcessView.as_view(
fields=["customer_name", "address", "toppings"]
)
).Next(this.bake)
bake = flow.View(
UpdateProcessView.as_view(fields=["baking_time"])
).Next(this.deliver)
deliver = flow.View(
UpdateProcessView.as_view(fields=["tips_received"])
).Next(this.end)
end = flow.End()
3. Add URLs
Register the workflow with the frontend:
from django.urls import path
from viewflow.contrib.auth import AuthViewset
from viewflow.urls import Application, Site
from viewflow.workflow.flow import FlowAppViewset
from my_pizza.flows import PizzaFlow
site = Site(
title="Pizza Flow Demo",
viewsets=[
FlowAppViewset(PizzaFlow, icon="local_pizza"),
]
)
urlpatterns = [
path("accounts/", AuthViewset().urls),
path("", site.urls),
]
4. Run migrations and start the server
Run migrations, start Django, and open the browser. You can now create and track pizza orders through the workflow.
Next steps: https://docs.viewflow.io/workflow/writing.html
Documentation
Latest version: http://docs.viewflow.io/
Version 1.xx: http://v1-docs.viewflow.io
Demo
Cookbook
Code samples and examples: https://github.com/viewflow/cookbook
Stay updated
[Subscribe to our newsletter][newsletter] for release notes, Django low-code tips, and notes on shipping business apps fast.
License
Viewflow is an Open Source project licensed under the terms of the AGPL license - The GNU Affero General Public License v3.0 with the Additional Permissions described in LICENSE_EXCEPTION
The AGPL license with Additional Permissions is a free software license that allows commercial use and distribution of the software. It is similar to the GNU GCC Runtime Library license, and it includes additional permissions that make it more friendly for commercial development.
If you use Linux already, this package license likely won't bring anything new to your stack.
Viewflow PRO has a commercial-friendly license allowing private forks and modifications of Viewflow. You can find the commercial license terms in COMM-LICENSE.
Changelog
For older releases, see CHANGELOG.rst.
2.4.0 2026-07-30
The largest feature release of the 2.x line: complete BPMN 2.0 node coverage, document-oriented JSON Store fields, and a drop-in replacement for django-fsm.
Workflow and BPMN
- New database-backed
flow.Timerandflow.StartTimer(interval=...)nodes. The due moment is stored on the task row (newTask.scheduledfield, migration included), so a timer survives a broker restart, unlikecelery.Timer. Due timers fire from theworkflow_timersmanagement command or theworkflow_fire_timerscelery beat task - Boundary events, declared on the host task before
.Next():.OnTimeout(delay, then)for deadlines and escalation,.OnError(then, code=...)to catch a background task failure. Interrupting by default;interrupting=Falsestarts a parallel path flow.TerminateEnd()cancels all other active tasks and finishes the process;flow.ErrorEnd(code)fails it. Inside a subprocess,ErrorEndmarks the parent taskERROR, so the parent's.OnError(..., code=...)boundary catches it- Compensation:
.CompensateWith(this.handler)registers an undo handler on any task, andflow.CompensateThrow()runs the handlers of completed tasks in reverse completion order, each at most once - New intermediate events:
MessageCatch/MessageThrow,SignalCatch/SignalThrow(one throw releases every armed catch, across processes and flow classes),EscalationThrowwith a non-interrupting.OnEscalationboundary, andConditionalCatch, which waits until a condition over process data holds - New task types:
flow.SendHandle,flow.BusinessRule, andflow.ManualTaskfor work done outside any system, marked done with a no-field confirmation.NSubprocess(..., sequential=True)runs one child process at a time - BPMN 2.0 export overhaul: exported files validate against the official OMG
schema and open in bpmn.io and Camunda Modeler.
Switch,SubprocessandNSubprocessare no longer dropped from the export,Handlemaps to a receive task, celeryJobto a service task, and the new nodes above to their real BPMN counterparts. Download a flow as.bpmnfrom the chart view, the REST API (?format=bpmn), the diagram dialog, or theflowexportcommand - Chart layout: empty grid rows and columns are collapsed, cell collisions
resolved, parallel edge channels staggered and routed around node shapes, and
Ifbranches labeled yes/no - The flow diagram dialog is now pan- and zoom-able: scroll to zoom toward the cursor, drag to pan, pinch on touch, double-click to reset
- Every built-in control node is cancellable,
Flow.cancelraises the intendedFlowRuntimeErrorinstead ofAttributeErrorfor a node with nocanceltransition, and the process cancel view refuses cleanly instead of returning a 500 when a task can't be cancelled flow.Viewgained areassign_view_classhook that finishes the built-in reassign transition and shows a "Reassign" action on the task (off by default)- New cookbook samples, all in application code with no core changes:
substitute(reassignment),snooze(hide a task from the inbox until a chosen time, #219), anddynamic_subprocess(attach anotherNSubprocesschild while the parent task still runs, #258)
JSON Store
- Relation fields stored inside the JSON document, with no column, migration or
join table:
jsonstore.ForeignKey(pk under_id, lazy load,ModelChoiceFieldin forms),jsonstore.OneToOneField, andjsonstore.ManyToManyField(a manager withall/add/remove/set/clear/count). Non-integer primary keys, e.g.UUIDField, are supported (#366) jsonstore.EmbeddedModelwithEmbeddedFieldandEmbeddedListField: schema-only virtu