Trying to build a state-machine that stores state in the model or in settings.py rather then in the database, I wrote this small generic pre_save hook that lets me leave all the data in the Model.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class InvalidStateChange(Exception):
pass
def check_state_changes(sender, instance, **kwargs):
"""
Compare the existing object in the database with the data about to be
saved. If the state transition is invalid, abort the save.
"""
if instance.id: # without an instance id, this is a create action
old = sender.objects.get(pk=instance.id)
for state_dict in sender.VALID_STATE_CHANGES:
if state_dict['from'] == old.state and instance.state == state_dict['to']:
return True
raise InvalidStateChange(
"%s can't go from %s to %s" % (
sender.__name__,
old.state,
instance.state,
)
)
pre_save.connect(check_state_changes, Model)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
even simpler with tuples instead of dictionaries
states = ((from_state, to_state),)
for from_state, to_state in sender.VALID_STATE_CHANGES: if from_state == old.state and to_state == instance.state: return True
#
Please login first before commenting.