By default, state variable is attached to any model object that is passed to Machine object initalisation in transitions library. Passing model_attribute will allow us to define custom state attribute. This wasn't obvious while going through the document. TL;DR 📖🥱😜
https://github.com/pytransitions/transitions
Also django-transitions is like experimental repo and maintained since Jan 2019. So I was looking for the solution without using it. Even if we use it mentioned only about setting custom name in Mixins. Does not make sense to just to use mixins for custom variables. So example I shown in models.py is better way. Next, I need to see how I can inherit this feature into custom ModelField class.
Sample execution:
$ ./manage.py shell
Python 3.8.0 (default, Feb 25 2021, 22:10:10)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.23.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from testapp.models import Car
In [2]: car = Car(title="Ford", color="red")
In [3]: car
Out[3]: <Car: Red - Ford [On Factory]>
In [4]: car.state_field
Out[4]: 'on_factory'
In [5]: car.machine.states.keys()
Out[5]: odict_keys(['on_factory', 'in_showroom', 'sold'])
In [6]: car.sell()
---------------------------------------------------------------------------
MachineError Traceback (most recent call last)
... (suppressed tracback to shorten text length)
MachineError: "Can't trigger event sell from state on_factory!"
In [7]: car.buy()
Out[7]: True
In [8]: car.state_field
Out[8]: 'in_showroom'
In [9]: car.sell()
Out[9]: True
In [10]: car
Out[10]: <Car: Red - Ford [Sold]>
In [11]: Car.objects.all()
Out[11]: <QuerySet [<Car: Blue - Maruthi [In Showroom]>, <Car: Red - Ford [Sold]>]>
I got inspired to write this gist after looking at issue #111 and replied with the same code in the comment section.