django-fsm-log

raw JSON →
5.0.2 verified Mon Apr 27 auth: no python

A lightweight Django library that logs state transitions for models using django-fsm. Version 5.0.2 supports Django 3.2–5.1, Python 3.9–3.13, and switched to django-fsm-2. Released via Jazzband with monthly patches.

pip install django-fsm-log
error ImportError: cannot import name 'FSMStateLog' from 'fsm_log.models'
cause The model was renamed from FSMStateLog to StateLog in a previous major version.
fix
Change your import to: 'from fsm_log.models import StateLog'
error ModuleNotFoundError: No module named 'django_fsm'
cause django-fsm-log v4+ depends on django-fsm-2, not django-fsm. The django-fsm package is not installed.
fix
Run 'pip uninstall django-fsm' then 'pip install django-fsm-2', or let django-fsm-log pull it in automatically.
error django.core.management.base.SystemCheckError: ... model 'MyModel' has no attribute 'state' or transition not found
cause The FSMLogMixin may not be properly inheriting or the FSMField is misconfigured.
fix
Ensure FSMLogMixin is listed before models.Model in class definition, and that you have a valid FSMField with 'protected=True'.
breaking v4.0.0 switched from django-fsm to django-fsm-2 as a dependency. If you have django-fsm pinned in your requirements, uninstall it and use django-fsm-2 instead.
fix Run 'pip uninstall django-fsm' and ensure django-fsm-2 is installed.
breaking v4.0.0 dropped support for Python 3.7, 3.8 and Django 2.2, 4.0. Upgrade your environment if needed.
fix Use Python >=3.9 and Django >=3.2 (but <5.2 for now).
deprecated The model class used to be called 'FSMStateLog' in versions <3.x. In current versions it is 'StateLog'.
fix Import 'StateLog' from 'fsm_log.models' instead.
gotcha FSMLogMixin must be placed before 'models.Model' in the class inheritance, otherwise the mixin's save method may not get called.
fix Always define your model as 'class MyModel(FSMLogMixin, models.Model):' - mixin first.
gotcha The decorator 'fsm_log_description' must be placed above @transition, not below, otherwise it won't capture the description.
fix Ensure 'fsm_log_description' is on top of 'transition': @fsm_log_description('desc')\n@transition(...)

Add FSMLogMixin to your model and every transition will be logged automatically to StateLog.

from django.db import models
from django_fsm import FSMField, transition
from fsm_log.mixins import FSMLogMixin

class Article(FSMLogMixin, models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    state = FSMField(default='draft', protected=True)

    @transition(field=state, source='draft', target='published')
    def publish(self):
        pass

# usage
article = Article.objects.create(title='Test', content='...')
article.publish()
article.save()
from fsm_log.models import StateLog
log_entries = StateLog.objects.filter(object_id=article.pk)
print(log_entries.count())  # >0