Frontend Viewset

Integrate FSM with Viewflow’s frontend viewsets to expose transitions as user actions.

Basic Integration

# viewset.py

from viewflow.fsm import FlowViewsMixin
from viewflow.views import ModelViewSet
from .flow import ReportFlow
from .models import Report

class ReportViewSet(FlowViewsMixin, ModelViewSet):
    model = Report
    flow_class = ReportFlow

    queryset = Report.objects.all()
    list_display = ['id', 'text', 'state_field']
    detail_actions = ['approve', 'reject', 'publish']

This adds transition buttons to detail views and handles permission checks automatically.

Custom Transition Forms

For transitions that need user input:

# forms.py

from django import forms
from .models import Report

class ApproveForm(forms.ModelForm):
    comment = forms.CharField(widget=forms.Textarea)

    class Meta:
        model = Report
        fields = []

# viewset.py

class ReportViewSet(FlowViewsMixin, ModelViewSet):
    # ...previous configuration...

    def get_transition_form_class(self, transition_name):
        if transition_name == 'approve':
            return ApproveForm
        return super().get_transition_form_class(transition_name)

    def perform_transition(self, instance, transition_name, form=None):
        flow = self.get_flow_instance(instance)
        if transition_name == 'approve' and form is not None:
            instance.approval_comment = form.cleaned_data['comment']

        transition = getattr(flow, transition_name)
        transition()

Template Customization

Override templates at these paths:

  • viewflow/fsm/{model_name}/{transition_name}.html - Specific transition
  • viewflow/fsm/{model_name}/transition_form.html - Model-specific form
  • viewflow/fsm/transition_form.html - Generic form

Example:

<!-- templates/viewflow/fsm/report/approve.html -->
{% extends "viewflow/fsm/transition_form.html" %}

{% block transition_title %}
    Approve Report #{{ object.pk }}
{% endblock %}

{% block transition_subtitle %}
    Please review the report carefully before approval.
{% endblock %}

State Visualization

The viewset provides a state machine chart at the chart/ URL:

# urls.py

from django.urls import path, include
from .viewset import ReportViewSet

urlpatterns = [
    path('reports/', include(ReportViewSet().urls)),
    # Creates /reports/chart/ for the FSM diagram
]