{"id":21148,"library":"django-fsm-log","title":"django-fsm-log","description":"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.","status":"active","version":"5.0.2","language":"python","source_language":"en","source_url":"https://github.com/jazzband/django-fsm-log","tags":["django","fsm","state-machine","logging","jazzband"],"install":[{"cmd":"pip install django-fsm-log","lang":"bash","label":"Standard install"}],"dependencies":[{"reason":"Replaced django-fsm in v4.0.0, breaking backward compatibility with older django-fsm","package":"django-fsm-2","optional":false},{"reason":"Required framework, version >=3.2","package":"Django","optional":false}],"imports":[{"note":"Common mistake: 'fsm_log.models' does not expose the mixin directly","symbol":"FSMLogMixin","correct":"from fsm_log.mixins import FSMLogMixin"},{"note":"Old django-fsm-log used FSMStateLog; renamed to StateLog in v3.x","wrong":"from fsm_log.models import FSMStateLog","symbol":"StateLog","correct":"from fsm_log.models import StateLog"},{"note":"Decorator lives in 'fsm_log.decorators', not in models","wrong":"from fsm_log.models import log_transition","symbol":"log_transition","correct":"from fsm_log.decorators import log_transition"}],"quickstart":{"code":"from django.db import models\nfrom django_fsm import FSMField, transition\nfrom fsm_log.mixins import FSMLogMixin\n\nclass Article(FSMLogMixin, models.Model):\n    title = models.CharField(max_length=100)\n    content = models.TextField()\n    state = FSMField(default='draft', protected=True)\n\n    @transition(field=state, source='draft', target='published')\n    def publish(self):\n        pass\n\n# usage\narticle = Article.objects.create(title='Test', content='...')\narticle.publish()\narticle.save()\nfrom fsm_log.models import StateLog\nlog_entries = StateLog.objects.filter(object_id=article.pk)\nprint(log_entries.count())  # >0","lang":"python","description":"Add FSMLogMixin to your model and every transition will be logged automatically to StateLog."},"warnings":[{"fix":"Run 'pip uninstall django-fsm' and ensure django-fsm-2 is installed.","message":"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.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Use Python >=3.9 and Django >=3.2 (but <5.2 for now).","message":"v4.0.0 dropped support for Python 3.7, 3.8 and Django 2.2, 4.0. Upgrade your environment if needed.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Import 'StateLog' from 'fsm_log.models' instead.","message":"The model class used to be called 'FSMStateLog' in versions <3.x. In current versions it is 'StateLog'.","severity":"deprecated","affected_versions":"<5.0.0"},{"fix":"Always define your model as 'class MyModel(FSMLogMixin, models.Model):' - mixin first.","message":"FSMLogMixin must be placed before 'models.Model' in the class inheritance, otherwise the mixin's save method may not get called.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure 'fsm_log_description' is on top of 'transition': @fsm_log_description('desc')\\n@transition(...)","message":"The decorator 'fsm_log_description' must be placed above @transition, not below, otherwise it won't capture the description.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-27T00:00:00.000Z","next_check":"2026-07-26T00:00:00.000Z","problems":[{"fix":"Change your import to: 'from fsm_log.models import StateLog'","cause":"The model was renamed from FSMStateLog to StateLog in a previous major version.","error":"ImportError: cannot import name 'FSMStateLog' from 'fsm_log.models'"},{"fix":"Run 'pip uninstall django-fsm' then 'pip install django-fsm-2', or let django-fsm-log pull it in automatically.","cause":"django-fsm-log v4+ depends on django-fsm-2, not django-fsm. The django-fsm package is not installed.","error":"ModuleNotFoundError: No module named 'django_fsm'"},{"fix":"Ensure FSMLogMixin is listed before models.Model in class definition, and that you have a valid FSMField with 'protected=True'.","cause":"The FSMLogMixin may not be properly inheriting or the FSMField is misconfigured.","error":"django.core.management.base.SystemCheckError: ... model 'MyModel' has no attribute 'state' or transition not found"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}