Get Django Forms Workflows up and running in 10 minutes!
Current release: v0.48.0 · Changelog · Full Docs index
- Python 3.10 or higher
- Django 5.2 or higher
- PostgreSQL 14+ (recommended) or MySQL 8.0+
# Core package
pip install django-forms-workflows
# With Excel spreadsheet field support
pip install "django-forms-workflows[excel]"
# With LDAP/AD support
pip install "django-forms-workflows[ldap]"
# With PDF export support
pip install "django-forms-workflows[pdf]"
# Everything
pip install "django-forms-workflows[all]"# settings.py
INSTALLED_APPS = [
# Django apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Required dependencies
'crispy_forms',
'crispy_bootstrap5',
# Django Forms Workflows
'django_forms_workflows',
# Your apps
# ...
]
# Crispy Forms Configuration
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"
# Forms Workflows Configuration (optional)
FORMS_WORKFLOWS = {
# Replace "Django Forms Workflows" branding across all templates
'SITE_NAME': 'My Org Workflows',
'ENABLE_APPROVALS': True,
'ENABLE_AUDIT_LOG': True,
'ENABLE_FILE_UPLOADS': True,
'MAX_FILE_SIZE': 10 * 1024 * 1024, # 10MB
}
# Optional context processor — injects site_name into templates
# Add this to your TEMPLATES setting:
# 'django_forms_workflows.context_processors.forms_workflows'# urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('forms/', include('django_forms_workflows.urls')),
]python manage.py migratepython manage.py createsuperuserpython manage.py runserverNavigate to http://localhost:8000/admin/ and log in.
- Go to Forms Workflows → Form Definitions
- Click Add Form Definition
- Fill in:
- Name: Travel Request
- Slug: travel-request
- Description: Request approval for business travel
- Is Active: ✓ (checked)
In the Form Fields inline section, add these fields:
- Field Name: destination
- Field Label: Destination
- Field Type: Single Line Text
- Required: ✓
- Order: 1
- Field Name: start_date
- Field Label: Start Date
- Field Type: Date
- Required: ✓
- Order: 2
- Field Name: end_date
- Field Label: End Date
- Field Type: Date
- Required: ✓
- Order: 3
- Field Name: purpose
- Field Label: Purpose of Travel
- Field Type: Multi-line Text
- Required: ✓
- Order: 4
- Field Name: estimated_cost
- Field Label: Estimated Cost
- Field Type: Decimal/Currency
- Required: ✓
- Order: 5
Click Save at the bottom of the page.
Navigate to http://localhost:8000/forms/travel-request/
You should see your form rendered beautifully with Bootstrap styling!
- Go to Authentication and Authorization → Groups
- Create a Travel Approvers group
- Optionally create a Finance Approvers group for a second stage
- Add your reviewer users to the appropriate groups
- Go to Forms Workflows → Workflow Definitions
- Click Add Workflow Definition
- Fill in:
- Form Definition: Travel Request
- Requires Approval: ✓
- Name Label: Travel Approval
- Approval Deadline Days: 5 (optional)
- Notification Cadence: Immediate
In the Workflow Stages inline, add:
- Name: Manager Review
- Order: 1
- Approval Logic: All must approve
- Approval Groups: Travel Approvers
- Allow Send Back: ✓ (optional, makes this a correction target for later stages)
- Name: Finance Review
- Order: 2
- Approval Logic: All must approve
- Approval Groups: Finance Approvers
- Approve Label: Sign Off (optional)
After saving the basic workflow, you can enable richer routing per stage:
- Dynamic assignee — set
assignee_form_field+assignee_lookup_type - Conditional stage — add
trigger_conditionsJSON - Reassignment — enable
allow_reassign - Editable submission data — enable
allow_edit_form_data - Manager-first approval — enable
requires_manager_approval
You can also create multiple WorkflowDefinition rows on the same form if you want parallel approval tracks.
- Submit the form as a regular user
- Log in as an approver
- Go to
http://localhost:8000/forms/approvals/ - Approve or reject the submission
- If you created multiple stages, confirm stage 2 is only created after stage 1 completes
For a full explanation of staged, parallel, conditional, and dynamic workflows, see Workflows Guide.
- Go back to your Travel Request form
- Add a new field:
- Field Name: requester_email
- Field Label: Your Email
- Field Type: Email Address
- Prefill Source: Current User - Email
- Order: 0
When you view the form while logged in, the email field will be automatically filled with your email address!
See LDAP Configuration Guide to:
- Authenticate users against Active Directory
- Prefill fields from LDAP attributes (department, title, manager, etc.)
- Use
assignee_lookup_type = "ldap"for manager-routing on approval stages
See Dynamic Assignees to route approval tasks to the specific individual named in a form field (by email, username, or display name).
See Workflows Guide for multi-stage, parallel-track, conditional, reassignment, editable-review, and deadline/reminder features.
See Visual Workflow Builder for what the builder supports today versus which advanced workflow settings still need Django Admin.
See Calculated Fields Guide to auto-compute read-only values from other field inputs, including spreadsheet-structured file uploads.
See Send Back for Correction to let approvers return submissions to any prior stage without terminating the workflow.
See Sub-Workflows Guide to create repeated child approval chains from a single parent submission.
See Database Integration Guide to:
- Query external databases for prefill data
- Use syntax like
{{ db.hr.employees.department }}
Copy templates from the package to your project:
mkdir -p templates/django_forms_workflows
python -c "import django_forms_workflows, os; print(os.path.dirname(django_forms_workflows.__file__))"
# Copy from the path printed above/templates/ to your templates/django_forms_workflows/Then customize as needed!
For async email notifications, batched digests, reminders, and deadline checks:
pip install celery redis# settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'# Run Celery worker
celery -A your_project worker -l info
# Run Celery beat scheduler (for reminders, auto-approval, and digest checks)
celery -A your_project beat -l info- Check that
is_active=Trueon the Form Definition - Check that you have permission to view the form
- Check the URL matches the form slug
- Check that the user is authenticated
- Check that the prefill source is configured correctly
- Check logs for errors:
python manage.py runserver --verbosity=2
- Check that a Workflow Definition exists for the form
- Check that the workflow has at least one stage
- Check that approval groups are configured
- Check that approvers are in the correct groups
Check out the example project in the repository:
git clone https://github.com/opensensor/django-forms-workflows.git
cd django-forms-workflows/example_project
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserverThe example project includes:
- Pre-configured forms
- Sample workflows
- LDAP integration example
- Database prefill example
- Custom data source example