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)