I'm using django-fsm to implement a state machine. The code looks like
def user_ok_to_check_me( instance, user):
...
class Job( models.Model):
# ... many screenfulls of code
@transition( field=state, target=BOOKING, source=CHECKING, permission=user_ok_to_check_me)
def fail_checking(self, **kwargs):
...
and it's working. Code readability is impaired by having that little utility function outside the class it belongs with, so I tried
class Job( models.Model):
# ... many screenfulls of code
@staticmethod
def user_ok_to_check_me( instance, user):
...
@transition( field=state, target=BOOKING, source=CHECKING, permission=user_ok_to_check_me)
def fail_checking(self, **kwargs):
which does not work. Not sure what user_ok_to_check_me does now do, it behaves like a no-op function always returning True even when all it does is return False
Why? And is there any way to declare this little function inside the class? (It's just a little bit too long to use lambda instance, user: )
Have found the answer, although I'm not sure I understand it.
The use of
ok_to_check_mein@transitionoccurs during the execution of the code that creates the class, and not during the instantiation thereof. So it needs a reference to the actual function defined above. Application of@staticmethodto that function replaces it by something else, and whatever that is, is not acceptable to the transition decorator.When the class is instantiated, the function gets bound to the instance. This does not, however, affect the reference to the function which
@transitionhas already stored in its internals. In this case the binding is harmless sinceinstanceandselfnormally refer to the same. In other cases one might want to delete the un-intended bound function from the instance in its__init__method (or just heavily document not to try to use it as an object method).