Mixins

Your Domain models can be inherited from a custom mixin to auto-instantiate a StateMachine.

MachineMixin

class statemachine.mixins.MachineMixin(*args, **kwargs)[source]

This mixing allows a model to automatically instantiate and assign an StateMachine.

state_field_name: str = 'state'

The model’s state field name that will hold the state value.

state_machine_attr: str = 'statemachine'

Name of the model’s attribute that will hold the machine instance.

state_machine_name: str = None

A fully qualified name of the class, where it can be imported.

Mixins example

Given a state machine definition:

>>> from statemachine import StateMachine, State

>>> from statemachine.mixins import MachineMixin

>>> class CampaignMachineWithKeys(StateMachine):
...     "A workflow machine"
...     draft = State('Draft', initial=True, value=1)
...     producing = State('Being produced', value=2)
...     closed = State('Closed', value=3)
...     cancelled = State('Cancelled', value=4)
...
...     add_job = draft.to.itself() | producing.to.itself()
...     produce = draft.to(producing)
...     deliver = producing.to(closed)
...     cancel = cancelled.from_(draft, producing)

It can be attached to a model using mixin and the fully qualified name of the class.

>>> class Workflow(MachineMixin):
...     state_machine_name = '__main__.CampaignMachineWithKeys'
...     state_machine_attr = 'sm'
...     state_field_name = 'workflow_step'
...
...     workflow_step = 1
...

When an instance of Workflow is created, it receives an instance of CampaignMachineWithKeys`` assigned using the state_machine_attrname. Also, thecurrent_stateis stored using thestate_field_name, in this case, workflow_step`.

>>> model = Workflow()

>>> isinstance(model.sm, CampaignMachineWithKeys)
True

>>> model.workflow_step
1

>>> model.sm.current_state == model.sm.draft
True

>>> model.sm.cancel()

>>> model.workflow_step
4

>>> model.sm.current_state == model.sm.cancelled
True

Note

On this example the state_machine_name is receiving a __main__ module due to the way autodoc works so we can have automated tests on the docs examples.

On your code, use the fully qualified path to the statemachine class.

See also

The Django integration section.