Viewflow looks for templates in a specific order, from most specific to most general.
For any view, Viewflow searches:
{app_label}/{flow_label}/{task_name}_{template_filename}{app_label}/{flow_label}/{template_filename}viewflow/workflow/{template_filename}Shows task information.
hello_world/hello_world/approve_task_detail.htmlhello_world/hello_world/task_detail.htmlviewflow/workflow/task_detail.htmlForm to start a new process.
{app_label}/{flow_label}/start.htmlviewflow/workflow/start.htmlForm to complete a task.
{app_label}/{flow_label}/{task_name}_task.html{app_label}/{flow_label}/task.htmlviewflow/workflow/task.htmlThis template appears in multiple views. Customize it to show process information consistently.
Lookup order:
{app_label}/{flow_label}/process_data.htmlviewflow/workflow/process_data.html{
'activation': TaskActivation instance,
'task': Task model instance,
'flow_class': The Flow class,
'flow_task': The specific Node instance,
'form': Form instance (if applicable)
}
{
'process': Process model instance,
'flow_class': The Flow class,
'tasks': QuerySet of Task instances
}
{
'flow_class': The Flow class (may be None for inbox/queue views),
'task_list': QuerySet of Task instances,
'filter_form': Task filter form (if enabled)
}
{
'flow_class': The Flow class,
'process_list': QuerySet of Process instances,
'filter_form': Process filter form (if enabled)
}
{# myapp/myapp/approve_task_detail.html #}
{% extends 'viewflow/workflow/task_detail.html' %}
{% block task_details %}
<div class="custom-task-details">
<div class="task-header">
<h3>{{ task.flow_task.task_title }}</h3>
<span class="task-status status-{{ task.status }}">
{{ task.get_status_display }}
</span>
</div>
<div class="task-meta">
<p><strong>Created:</strong> {{ task.created|date:"F j, Y, H:i" }}</p>
{% if task.owner %}
<p><strong>Assigned to:</strong>
{{ task.owner.get_full_name|default:task.owner.username }}
</p>
{% endif %}
</div>
<div class="task-actions">
{% if task|can_execute:request.user %}
<a href="{% url 'myapp:execute_task' process_pk=task.process_id task_pk=task.pk %}"
class="btn btn-primary">
Process Task
</a>
{% endif %}
</div>
</div>
{% endblock %}
{# myapp/myapp/process_data.html #}
<div class="process-data-container">
<h3>Process Information</h3>
<div class="process-field">
<label>Process ID:</label>
<span>{{ process.pk }}</span>
</div>
<div class="process-field">
<label>Started:</label>
<span>{{ process.created|date:"F j, Y, H:i" }}</span>
</div>
<div class="process-field">
<label>Status:</label>
<span class="status-badge status-{{ process.status }}">
{{ process.get_status_display }}
</span>
</div>
{% if process.artifact %}
<div class="process-field">
<label>Artifact:</label>
<a href="{{ process.artifact.get_absolute_url }}">View Details</a>
</div>
{% endif %}
</div>
{% load viewflow workflow %}
{# Task action URLs #}
<a href="{% task_action_url task 'assign' %}">Assign</a>
<a href="{% task_action_url task 'execute' %}">Execute</a>
<a href="{% task_action_url task 'unassign' %}">Unassign</a>
{# Process action URLs #}
<a href="{% process_action_url process 'cancel' %}">Cancel Process</a>
<a href="{% process_action_url process 'detail' %}">View Details</a>
{# Flow diagram #}
{% flow_diagram flow_class task=task %}
{# Permission checks #}
{% if task|can_execute:request.user %}
<button type="button">Execute Task</button>
{% endif %}
{% if task|can_assign:request.user %}
<button type="button">Assign Task</button>
{% endif %}