@@ -471,6 +471,32 @@ def set_state(self, instance, state):
471471 instance .__dict__ [self .attname ] = self .to_python (state )
472472
473473
474+ class FSMModelMixin (object ):
475+ """
476+ Mixin that allows refresh_from_db for models with fsm protected fields
477+ """
478+
479+ def _get_protected_fsm_fields (self ):
480+ def is_fsm_and_protected (f ):
481+ return isinstance (f , FSMFieldMixin ) and f .protected
482+ protected_fields = filter (is_fsm_and_protected , self ._meta .concrete_fields )
483+ return {f .attname for f in protected_fields }
484+
485+ def refresh_from_db (self , * args , ** kwargs ):
486+ fields = kwargs .pop ("fields" , None )
487+
488+ # Use provided fields, if not set then reload all non-deferred fields.0
489+ if not fields :
490+ deferred_fields = self .get_deferred_fields ()
491+ protected_fields = self ._get_protected_fsm_fields ()
492+ skipped_fields = deferred_fields .union (protected_fields )
493+
494+ fields = [f .attname for f in self ._meta .concrete_fields
495+ if f .attname not in skipped_fields ]
496+
497+ kwargs ['fields' ] = fields
498+ super (FSMModelMixin , self ).refresh_from_db (* args , ** kwargs )
499+
474500class ConcurrentTransitionMixin (object ):
475501 """
476502 Protects a Model from undesirable effects caused by concurrently executed transitions,
0 commit comments