Library internals

This page documents the internal mechanisms of django_xworkflows.

Binding to a workflow

The mechanism to bind a django model to a xworkflows.Workflow relies on the WorkflowEnabled and StateField classes.

class django_xworkflows.models.StateField(django.models.Field)

This class is a simple Django Field, specifically tuned for a Workflow.

It is internally backed by a CharField containing the name of the state.

Reading the value always returns a xworkflows.base.StateWrapper, writing checks that the value is a valid state or a valid state name.

workflow

Mandatory; holds the Workflow to which this StateField relates

choices

The workflow states, as a list of (name, title) tuples, for use in forms.

default

The name of the inital state of the workflow

max_length

The length of the longest state name in the workflow.

blank

Such a field cannot be blanked (otherwise, the workflow wouldn’t have a meaning).

null

Since the field cannot be empty, is cannot be null either.

south_field_triple(self)

Returns the south description of this field. When unfreezing, a fake Workflow will be retrieved with the same states and initial_state as present at freezing time.

This allows reading states that no longer exist in the workflow.

class django_xworkflows.models.WorkflowEnabled(models.Model)

This class inherits from Django’s Model class, performing some transformations on the subclass: each attr = StateField(SomeWorkflow, ...) attribute will enable XWorkflows’ transition detection and wrapping.

Most of this job is performed through WorkflowEnabledMeta.

_get_FIELD_display(self, field)

This method overrides the default django one to retrieve the title from a StateField field.

Transitions

Transitions mostly follow XWorkflows’ mechanism.

class django_xworkflows.models.TransactionalImplementationWrapper(xworkflows.base.ImplementationWrapper)

This specific wrapper runs all transition-related code (transition_check hooks, before_transition hooks, implementation, log_transition, after_transition hooks) in a single database transaction.

The TransactionalImplementationWrapper can be enabled by setting it to the implementation_class attribute of a xworkflows.Workflow or of a Workflow:

class MyWorkflow(models.Workflow):
    implementation_class = models.TransactionalImplementationWrapper
class django_xworkflows.models.Workflow(xworkflows.Workflow)

This xworkflows.Workflow subclass performs a few customization:

  • Logging transition logs in database
  • Saving updated objects after the transition
log_model

This holds the model to use to log to the database. If empty, no database logging is performed.

db_log(self, transition, from_state, instance, user=None, *args, **kwargs)

Logs the transition into the database, saving the following elements:

  • Name of the transition
  • Name of the initial state
  • GenericForeignKey to the modified instance
  • ForeignKey to the user responsible for the transition
  • timestamp of the operation

The default BaseTransitionLog model is django_xworkflows.xworkflow_log.models.TransitionLog, but an alternative one can be specified in log_model.

Hint

Override this method to log to a custom BaseTransitionLog without generic foreign keys.

log_transition(self, transition, from_state, instance, save=True, log=True, *args, **kwargs)

In addition to xworkflows.Workflow.log_transition(), additional actions are performed:

  • If save is True, the instance is saved.
  • If log is True, the db_log() method is called to register the transition in the database.

Transition logs

class django_xworkflows.models.BaseTransitionLog

This abstract model describes which fields are expected when logging a transition to the database.

The default for all WorkflowEnabled subclasses will be to log to django_xworkflows.xworkflow_log.models.TransitionLog instances.

This behaviour can be altered by setting the log_model attribute of Workflow definition.

modified_object

A GenericForeignKey to the WorkflowEnabled being modified.

transition

The name of the transition performed

Type :str
from_state

The name of the source state for the transition

Type :str
to_state

The name of the destination state for the transition

Type :str
timestamp

The time at which the transition occurred.

Type :datetime.datetime

An example BaseTransitionLog model is available in the django_xworkflows.xworkflow_log application. Including it to INSTALLED_APPS will enable database logging of transitions for all WorkflowEnabled subclasses.

class django_xworkflows.xworkflow_log.models.TransitionLog(BaseTransitionLog)

This specific BaseTransitionLog also stores the user responsible for the transition, if provided.

The exact Model to use for that foreign key can be set in the XWORKFLOWS_USER_MODEL setting (defaults to 'auth.User', which uses django.contrib.auth.models.User).

Internals

Note

These classes are private API.

class django_xworkflows.models.WorkflowEnabledMeta(xworkflows.base.WorkflowEnabledMeta)

This metaclass is responsible for parsing a class definition, detecting all StateField and collecting/defining the associated TransactionalImplementationWrapper.

_find_workflows(mcs, attrs)

Collect all StateField from the given attrs (the default version collects Workflow subclasses instead)

_add_workflow(mcs, field_name, state_field, attrs)

Perform necessay actions to register the Workflow stored in a StateField defined at field_name into the given attributes dict.

It differs from the base implementation which adds a StateProperty instead of keeping the StateField.

Parameters:
  • field_name (str) – The name of the attribute at which the StateField was defined
  • state_field (StateField) – The StateField wrapping the Workflow
  • attrs (dict) – The attributes dictionary to update.

Table Of Contents

Previous topic

django-xworkflows documentation

Next topic

ChangeLog

This Page