@@ -126,26 +126,26 @@ def save(self, *args, **kwargs):
126126 is_new = self ._state .adding
127127
128128 if is_new :
129- self ._run_hooked_methods (BEFORE_CREATE )
129+ self ._run_hooked_methods (BEFORE_CREATE , ** kwargs )
130130 else :
131- self ._run_hooked_methods (BEFORE_UPDATE )
131+ self ._run_hooked_methods (BEFORE_UPDATE , ** kwargs )
132132
133- self ._run_hooked_methods (BEFORE_SAVE )
133+ self ._run_hooked_methods (BEFORE_SAVE , ** kwargs )
134134 save (* args , ** kwargs )
135- self ._run_hooked_methods (AFTER_SAVE )
135+ self ._run_hooked_methods (AFTER_SAVE , ** kwargs )
136136
137137 if is_new :
138- self ._run_hooked_methods (AFTER_CREATE )
138+ self ._run_hooked_methods (AFTER_CREATE , ** kwargs )
139139 else :
140- self ._run_hooked_methods (AFTER_UPDATE )
140+ self ._run_hooked_methods (AFTER_UPDATE , ** kwargs )
141141
142142 self ._initial_state = self ._snapshot_state ()
143143
144144 @transaction .atomic
145145 def delete (self , * args , ** kwargs ):
146- self ._run_hooked_methods (BEFORE_DELETE )
146+ self ._run_hooked_methods (BEFORE_DELETE , ** kwargs )
147147 value = super ().delete (* args , ** kwargs )
148- self ._run_hooked_methods (AFTER_DELETE )
148+ self ._run_hooked_methods (AFTER_DELETE , ** kwargs )
149149 return value
150150
151151 @classmethod
@@ -188,7 +188,7 @@ def _watched_fk_model_fields(cls) -> List[str]:
188188 def _watched_fk_models (cls ) -> List [str ]:
189189 return [_ .split ("." )[0 ] for _ in cls ._watched_fk_model_fields ()]
190190
191- def _run_hooked_methods (self , hook : str ) -> List [str ]:
191+ def _run_hooked_methods (self , hook : str , ** kwargs ) -> List [str ]:
192192 """
193193 Iterate through decorated methods to find those that should be
194194 triggered by the current hook. If conditions exist, check them before
@@ -204,14 +204,24 @@ def _run_hooked_methods(self, hook: str) -> List[str]:
204204 when_field = callback_specs .get ("when" )
205205 when_any_field = callback_specs .get ("when_any" )
206206
207+ # None is explicit instead of an empty list; since Django aborts the save with an empty list
208+ update_fields = kwargs .get ("update_fields" , None )
209+ update_fields_exist = update_fields is not None
210+
207211 if when_field :
212+ if update_fields_exist and when_field not in update_fields :
213+ continue
208214 if not self ._check_callback_conditions (when_field , callback_specs ):
209215 continue
210216 elif when_any_field :
217+ filtered_when_any_fields = when_any_field
218+ if update_fields_exist :
219+ filtered_when_any_fields = list (set (update_fields ) & set (when_any_field )) # Intersected.
220+
211221 if not any (
212222 [
213223 self ._check_callback_conditions (field_name , callback_specs )
214- for field_name in when_any_field
224+ for field_name in filtered_when_any_fields
215225 ]
216226 ):
217227 continue
0 commit comments