
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Provides persistence of the transitions of your fsm's models. Backed by the excellent Django FSM package.
Logs can be accessed before a transition occurs and before they are persisted to the database by enabling a cached backend. See Advanced Usage
fsm_log_description
now accepts a default description parameterfsm_log_description
decoratorget_state_display
with FSMIntegerField (#63)fsm_log_description
decorator (#1, #67)1.6
, 1.7
, 1.9
.First, install the package with pip. This will automatically install any dependencies you may be missing
pip install django-fsm-log
Register django_fsm_log in your list of Django applications:
INSTALLED_APPS = (
...,
'django_fsm_log',
...,
)
Then migrate the app to create the database table
python manage.py migrate django_fsm_log
The app listens for the django_fsm.signals.post_transition
signal and
creates a new record for each transition.
To query the log:
from django_fsm_log.models import StateLog
StateLog.objects.all()
# ...all recorded logs...
By default transitions get recorded for all models. Logging can be disabled for
specific models by adding their fully qualified name to DJANGO_FSM_LOG_IGNORED_MODELS
.
DJANGO_FSM_LOG_IGNORED_MODELS = ('poll.models.Vote',)
for_
Manager MethodFor convenience there is a custom for_
manager method to easily filter on the generic foreign key:
from my_app.models import Article
from django_fsm_log.models import StateLog
article = Article.objects.all()[0]
StateLog.objects.for_(article)
# ...logs for article...
by
DecoratorWe found that our transitions are commonly called by a user, so we've added a decorator to make logging this easy:
from django.db import models
from django_fsm import FSMField, transition
from django_fsm_log.decorators import fsm_log_by
class Article(models.Model):
state = FSMField(default='draft', protected=True)
@fsm_log_by
@transition(field=state, source='draft', target='submitted')
def submit(self, by=None):
pass
With this the transition gets logged when the by
kwarg is present.
article = Article.objects.create()
article.submit(by=some_user) # StateLog.by will be some_user
description
DecoratorDecorator that allows to set a custom description (saved on database) to a transitions.
from django.db import models
from django_fsm import FSMField, transition
from django_fsm_log.decorators import fsm_log_description
class Article(models.Model):
state = FSMField(default='draft', protected=True)
@fsm_log_description(description='Article submitted') # description param is NOT required
@transition(field=state, source='draft', target='submitted')
def submit(self, description=None):
pass
article = Article.objects.create()
article.submit() # logged with "Article submitted" description
article.submit(description="Article reviewed and submitted") # logged with "Article reviewed and submitted" description
.. TIP:: The "description" argument passed when calling ".submit" has precedence over the default description set in the decorator
The decorator also accepts a allow_inline
boolean argument that allows to set the description inside the transition method.
from django.db import models
from django_fsm import FSMField, transition
from django_fsm_log.decorators import fsm_log_description
class Article(models.Model):
state = FSMField(default='draft', protected=True)
@fsm_log_description(allow_inline=True)
@transition(field=state, source='draft', target='submitted')
def submit(self, description=None):
description.set("Article submitted")
article = Article.objects.create()
article.submit() # logged with "Article submitted" description
There is an InlineForm available that can be used to display the history of changes.
To use it expand your own AdminModel
by adding StateLogInline
to its inlines:
from django.contrib import admin
from django_fsm_log.admin import StateLogInline
@admin.register(FSMModel)
class FSMModelAdmin(admin.ModelAdmin):
inlines = [StateLogInline]
You can change the behaviour of this app by turning on caching for StateLog records.
Simply add DJANGO_FSM_LOG_STORAGE_METHOD = 'django_fsm_log.backends.CachedBackend'
to your project's settings file.
It will use your project's default cache backend by default. If you wish to use a specific cache backend, you can add to
your project's settings:
DJANGO_FSM_LOG_CACHE_BACKEND = 'some_other_cache_backend'
The StateLog object is now available after the django_fsm.signals.pre_transition
signal is fired, but is deleted from the cache and persisted to the database after django_fsm.signals.post_transition
is fired.
This is useful if:
django_fsm.signals.post_transition
has been firedAccess to the pending StateLog record is available via the pending_objects
manager
from django_fsm_log.models import StateLog
article = Article.objects.get(...)
pending_state_log = StateLog.pending_objects.get_for_object(article)
pip install tox
tox
We use ruff, black and more, all configured and check via pre-commit. Before committing, run the following:
pip install pre-commit
pre-commit install
FAQs
Transition's persistence for django-fsm
We found that django-fsm-log demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.