@@ -205,27 +205,35 @@ def _run_hooked_methods(self, hook: str, **kwargs) -> List[str]:
205205
206206 when_field = callback_specs .get ("when" )
207207 when_any_field = callback_specs .get ("when_any" )
208-
209- # None is explicit instead of an empty list; since Django aborts the save with an empty list
210208 update_fields = kwargs .get ("update_fields" , None )
211- update_fields_exist = update_fields is not None
209+ is_partial_fields_update = update_fields is not None
212210
213211 if when_field :
214- if update_fields_exist and when_field not in update_fields :
215- continue
216- if not self ._check_callback_conditions (when_field , callback_specs ):
212+ if not self ._check_callback_conditions (
213+ when_field ,
214+ callback_specs ,
215+ is_synced = (
216+ is_partial_fields_update is False
217+ or when_field in update_fields
218+ ),
219+ ):
217220 continue
218221 elif when_any_field :
219- filtered_when_any_fields = when_any_field
220- if update_fields_exist :
221- filtered_when_any_fields = list (set (update_fields ) & set (when_any_field )) # Intersected.
222-
223- if not any (
224- [
225- self ._check_callback_conditions (field_name , callback_specs )
226- for field_name in filtered_when_any_fields
227- ]
228- ):
222+ any_condition_matched = False
223+
224+ for field_name in when_any_field :
225+ if self ._check_callback_conditions (
226+ field_name ,
227+ callback_specs ,
228+ is_synced = (
229+ is_partial_fields_update is False
230+ or field_name in update_fields
231+ ),
232+ ):
233+ any_condition_matched = True
234+ break
235+
236+ if not any_condition_matched :
229237 continue
230238
231239 # Save method name before potentially wrapping with `on_commit`
@@ -252,8 +260,13 @@ def _run_hooked_methods(self, hook: str, **kwargs) -> List[str]:
252260
253261 return fired
254262
255- def _check_callback_conditions (self , field_name : str , specs : dict ) -> bool :
256- if not self ._check_has_changed (field_name , specs ):
263+ def _check_callback_conditions (
264+ self , field_name : str , specs : dict , is_synced : bool
265+ ) -> bool :
266+ if not self ._check_has_changed (field_name , specs , is_synced ):
267+ return False
268+
269+ if not self ._check_changes_to_condition (field_name , specs , is_synced ):
257270 return False
258271
259272 if not self ._check_is_now_condition (field_name , specs ):
@@ -268,12 +281,12 @@ def _check_callback_conditions(self, field_name: str, specs: dict) -> bool:
268281 if not self ._check_is_not_condition (field_name , specs ):
269282 return False
270283
271- if not self ._check_changes_to_condition (field_name , specs ):
272- return False
273-
274284 return True
275285
276- def _check_has_changed (self , field_name : str , specs : dict ) -> bool :
286+ def _check_has_changed (self , field_name : str , specs : dict , is_synced : bool ) -> bool :
287+ if not is_synced :
288+ return False
289+
277290 has_changed = specs ["has_changed" ]
278291 return has_changed is None or has_changed == self .has_changed (field_name )
279292
@@ -291,7 +304,12 @@ def _check_was_not_condition(self, field_name: str, specs: dict) -> bool:
291304 was_not = specs ["was_not" ]
292305 return was_not is NotSet or self .initial_value (field_name ) != was_not
293306
294- def _check_changes_to_condition (self , field_name : str , specs : dict ) -> bool :
307+ def _check_changes_to_condition (
308+ self , field_name : str , specs : dict , is_synced : bool
309+ ) -> bool :
310+ if not is_synced :
311+ return False
312+
295313 changes_to = specs ["changes_to" ]
296314 return any (
297315 [
0 commit comments