Django Admin support

PRO ONLY

viewflow.fsm.FlowAdminMixin adds transitions views to the standard Django Model admin interface.

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

If your flow class has single constructor with only one argument - the django object been wrapped, the admin interface would automatically discover that

The flow class construction could be overridden in the get_object_flow method

from django.contrib import admin
from viewflow import fsm
from .flows import ReviewFlow
from .models import Review


@admin.register(Review)
class ReviewFlowAdmin(fsm.FlowAdminMixin, admin.ModelAdmin):
    readonly_fields = ('state', )

    flow_state = ReviewFlow.state

    def get_object_flow(self, request, obj):
        return ReviewFlow(
            obj, user=request.user,
            ip_address=request.META.get('REMOTE_ADDR')
        )

Change object data

get_transition_fields method could be overridden to allow an admin user change specific object fields alongside with transition execution.

def get_transition_fields(self, request, obj, slug):
    if slug == 'approve':
        return ['text', 'comment']

Custom transition view

To completely override transition view, specify custom url entry in the get_urls method

def get_urls(self):
    return [path(
        '<path:object_id>/transition/reject/',
        self.admin_site.admin_view(self.reject_view),
    )] + super().get_urls()

def reject_view(self, request, object_id):
    obj = get_object_or_404(self.model, pk=object_id)
    flow = self.get_object_flow(request, obj)

    if not flow.reject.has_perm(request.user) or not flow.reject.can_proceed():
        raise PermissionDenied

    if request.method == "POST":
        flow.reject()
        obj.save()
        return redirect('../../')

    return render(request, ...)

django-guardian

FlowAdminMixin plays well with reversion.admin.VersionAdmin