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)