-
-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Having a StateLog on object creation with the default state? #145
Comments
django-fsm-log offers persistence of the transition. When we initialize a state machine, there is no transition called, per nature I would say. |
@ticosax Thanks for the reply. I was thinking of this kind of solution too. I'll try this and let you know about the result on this thread. |
Yep, it seems to work as expected. I'll detail my solution here to potentially:
The mixin # Reusable enum choices
INITIALIZED = "INITIALIZED", "initialisé"
CREATED = "CREATED", "créé"
class FSMTransitionOnCreateMixin(models.Model):
"""
Add an automatic new transition (from INITIALIZED to CREATED) for a class
with a `state` attribute.
The purpose is to have a transition log as soon as an object is created.
"""
class Meta:
abstract = True
@fsm_log_by
@transition(
field="state",
source=INITIALIZED[0],
target=CREATED[0],
)
def to_created(self, by=None, description=None):
pass
def save(self, *args, **kwargs):
"""
- super() needs to be run before, as django fsm needs object_id to build the log
- adding state must be recorded before calling super(), as it would become false
anyway after calling super().
"""
adding = self._state.adding # save the state
super().save(*args, **kwargs)
if adding is True:
self.to_created() Example usage in a class with a state from core.mixins.fsm import CREATED, INITIALIZED, FSMTransitionOnCreateMixin
class MandateState(models.TextChoices):
INITIALIZED = INITIALIZED # avoid repetition
CREATED = CREATED # avoid repetition
SENT = "SENT", "envoyé au client"
SIGNED = "SIGNED", "signé par le client"
ONGOING_SEARCH = "ONGOING_SEARCH", "recherche en cours"
PAUSED_SEARCH = "PAUSED_SEARCH", "recherche en pause"
ENDED = "ENDED", "recherche terminée"
class Mandate(FSMTransitionOnCreateMixin, models.Model):
# ...
state = FSMField(
"statut",
choices=MandateState.choices,
default=MandateState.INITIALIZED,
protected=True,
) |
Or you can define the initial transition in a signal: from django.db.models.signals import post_save
from django.dispatch import receiver
from django_fsm.signals import post_transition
from project.foobar.models import Entity
@receiver(post_save, sender=Entity)
def trigger_initial_transition(sender, instance, created, **kwargs):
if created:
instance.baz() Assuming you have a model like so: from django.db import models
from django_fsm import FSMIntegerField
from django_fsm import transition
class Entity(models.Model):
...
class State(models.IntegerChoices):
_NONE = 0, "-"
FOO = 1, "foo"
BAR = 2, "bar"
...
state = FSMIntegerField(
default=State._NONE,
choices=State.choices,
blank=True,
)
@transition(
state,
source=[State._NONE],
target=State.FOO,
)
def baz(self):
""""""
... |
In my app, I'm trying to show the full life cycles of objects using FSM.
While I love django-fsm-log for that purpose, the object creation itself is missing from these logs, as it's not a transition.
But after all, we could see this first step as a transition from the "
None
state" to the "created
(default) state".That's why I was wondering what is the best way, to create a StateLog instance when my object is created with the default state.
For example:
Thanks.
The text was updated successfully, but these errors were encountered: