vision-it-request-forms-frontend (0.1.12)
Installation
pip install --index-url vision-it-request-forms-frontendAbout this package
Frontend Django app for Vision IT Request Forms — templates and HTMX views
Vision IT Request Forms
A self-service IT request form system for Django projects. Built for Datapath's Vision Dashboard but designed to run standalone. End users browse a form catalog, fill out structured multi-section forms, and submit requests that are routed through configurable approval workflows and outbound connectors (ConnectWise, email, Slack, webhooks).
Packages
This repo produces two installable Django apps:
| Package | PyPI name | Django app label | Purpose |
|---|---|---|---|
| Frontend | vision-it-request-forms-frontend |
vision_it_request_forms |
HTMX views, templates, form catalog |
| Backend | vision-it-request-forms-backend |
vision_it_support_forms |
Models, DRF API, approvals, connectors |
Both packages are published to the Datapath Gitea PyPI registry.
Requirements
- Python 3.11+
- Django 5.2+
- djangorestframework 3.15+
- django-groups-manager 1.x
- django-admin-sortable2 2.x
Installation
1. Configure the private registry
Add the Datapath registry as an extra index in your pip.conf or requirements.txt header:
--extra-index-url https://git.mydatapath.com/api/packages/Datapath/pypi/simple
2. Install both packages
pip install vision-it-request-forms-backend vision-it-request-forms-frontend
3. Add apps to INSTALLED_APPS
The backend must come before the frontend. Both rest_framework, adminsortable2, and groups_manager are required dependencies:
INSTALLED_APPS = [
# ...
"rest_framework",
"adminsortable2",
"groups_manager",
"vision_it_support_forms", # backend — models, API, connectors
"vision_it_request_forms", # frontend — views, templates
]
4. Configure Django REST Framework
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"vision_it_support_forms.authentication.BearerTokenAuthentication",
"rest_framework.authentication.SessionAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
"PAGE_SIZE": 25,
}
5. Add the context processor
The frontend views inject API connection details and user group information via a context processor:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"vision_it_request_forms.context_processors.it_requests_context",
],
},
}
]
6. Mount the URL patterns
# urls.py
from django.urls import path, include
urlpatterns = [
# Backend DRF API → /api/v1/it-requests/
path("api/v1/", include("vision_it_support_forms.urls")),
# Frontend views → /it-requests/
path("it-requests/", include("vision_it_request_forms.urls")),
]
7. Set required environment variables
# Static bearer token used by the frontend to call the DRF API.
# In production with Vision Dashboard, the Wristband access token is used instead.
IT_REQUESTS_API_TOKEN=your-static-token-here
# Leave empty if frontend and API are on the same host (typical for standalone use).
IT_REQUESTS_API_BASE_URL=
Add the corresponding Django settings (or read them from the environment):
IT_REQUESTS_API_TOKEN = os.getenv("IT_REQUESTS_API_TOKEN", "")
IT_REQUESTS_API_BASE_URL = os.getenv("IT_REQUESTS_API_BASE_URL", "")
8. Run migrations
python manage.py migrate
Connector Configuration
Connectors are configured in the Django admin under Vision IT Support Forms → Connector configs. Each connector type expects specific fields in its config JSON object:
ConnectWise
{
"company": "mycompany",
"url": "https://na.myconnectwise.net",
"client_id": "...",
"public_key": "...",
"private_key": "...",
"board_id": 123,
"board_name": "Service",
"default_status_id": 1,
"default_type_id": 2
}
Set environment variables and reference them, or store values directly in the admin.
SendGrid (email)
{
"to_email": "helpdesk@example.com",
"from_email": "noreply@example.com",
"subject_template": "New IT Request: {form_name}"
}
Requires SENDGRID_API_KEY environment variable.
Slack (webhook)
{
"webhook_url": "https://hooks.slack.com/services/..."
}
Slack (bot)
{
"token": "xoxb-...",
"channel": "#it-requests"
}
Generic webhook / n8n
{
"url": "https://your-webhook-endpoint.example.com/it-requests",
"headers": {
"Authorization": "Bearer ..."
}
}
Running the Job Processor
Connector dispatches are queued in an outbox and processed by a management command. Run it on a schedule (cron, systemd timer, or a process manager):
python manage.py it_requests_process_jobs
Jobs are retried up to 5 times with exponential backoff (1 min, 5 min, 15 min, 60 min), then marked as permanently failed.
Approval Workflows
Approval configuration is per-form and managed in the Django admin under Approval configs and Approval rules.
- Require all: all rules must produce an approved decision before the submission advances.
- Require any: one approved decision from any eligible approver is sufficient.
Approvers can be specified as:
- A specific Django user
- Any member of a group
- Any user holding a named role within a group (e.g.
it-forms-admin)
Leadership users (those with an it-forms-admin role in their group) access pending submissions at /it-requests/leadership/.
Form Structure
Forms are built in the admin as a hierarchy:
FormTemplate
└── SubForm (ordered, with optional conditional display rules)
└── Field (ordered, typed, with optional validation rules)
Field types: text, textarea, integer, decimal, email, phone, date, datetime, boolean, select, multi_select, radio, user_picker, group_picker
SubForms can be universal (shared across all tenants) or group-specific (overrides the universal version for a particular tenant group). The schema resolver picks the most specific variant at render and submission time.
Form versioning: the full resolved schema is snapshotted into a FormVersion record at the moment a user submits. Historical submissions always render against the version that was current when they were created, regardless of later edits.
Vision Dashboard Integration
When mounted in Vision Dashboard, the host project supplies wristband, user_feature_access, and company_feature_access via its context processors. The templates guard all of these with {% if %} checks so the app runs without them in standalone mode.
Authentication in production uses the Wristband access token injected by Vision Dashboard into HTMX request headers via token.js.
Development Setup
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
cd djangoappdev
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver # http://localhost:8000/it-requests/
Run tests:
cd djangoappdev
python manage.py test
# or
pytest