Expose REST Interface

viewflow.fsm.FlowRESTMixin adds additional REST endpoints to a `ModelViewset

After you defined a flow around django models as described in Wrapping Django Models you can add FlowRESTMixin to the ModelViewset and define flow_state attribute

If your flow class has single constructor with only one argument - the django object been wrapped, the rest interface would automatically use it

The flow class construction could be overridden in the get_object_flow method

from viewflow.fsm import FlowRESTMixin

class ReviewViewSet(FlowRESTMixin, viewsets.ModelViewSet):
    flow_state = ReviewFlow.stage
    queryset = Review.objects.all()
    serializer_class = ReviewSerializer

    def get_object_flow(self, request, obj):
        """Instantiate the flow without default constructor"""
        return ReviewFlow(
            obj, user=request.user,
            ip_address=request.META.get('REMOTE_ADDR')
    )

Custom per-transition serializer

def get_serializer_class(self):
    if self.action in ('approve', 'reject'):
        return ReviewAuditSerializer
    return super().get_serializer_class()

Custom transition action

@action(methods=['POST'], detail=True, url_path='transition/approve')
def approve(self, request, *args, **kwargs):
    instance = self.get_object()
    flow = self.get_object_flow(request, instance)

    if not flow.approve.has_perm(request.user):
        raise PermissionDenied

    if not flow.approve.can_proceed():
        raise ValidationError(_('Transition is not allowed'))

    serializer = self.get_serializer(instance, data=request.data, partial=True)
    serializer.is_valid(raise_exception=True)
    self.perform_update(serializer)

    flow.approve()

    return Response(serializer.data)