@@ -901,9 +901,29 @@ def diff_against(self, old_history, excluded_fields=None, included_fields=None):
901
901
changes .append (ModelChange (field , old_value , current_value ))
902
902
changed_fields .append (field )
903
903
904
+ # Separately compare m2m fields:
904
905
for field in old_history ._history_m2m_fields :
905
- old_rows = list (getattr (old_history , field .name ).values_list ())
906
- new_rows = list (getattr (self , field .name ).values_list ())
906
+ # First retrieve a single item to get the field names from:
907
+ reference_history_m2m_item = (
908
+ getattr (old_history , field .name ).first ()
909
+ or getattr (self , field .name ).first ()
910
+ )
911
+ history_field_names = []
912
+ if reference_history_m2m_item :
913
+ # Create a list of field names to compare against.
914
+ # The list is generated without the primary key of the intermediate
915
+ # table, the foreign key to the history record, and the actual 'history'
916
+ # field, to avoid false positives while diffing.
917
+ history_field_names = [
918
+ f .name
919
+ for f in reference_history_m2m_item ._meta .fields
920
+ if f .editable and f .name not in ["id" , "m2m_history_id" , "history" ]
921
+ ]
922
+
923
+ old_rows = list (
924
+ getattr (old_history , field .name ).values (* history_field_names )
925
+ )
926
+ new_rows = list (getattr (self , field .name ).values (* history_field_names ))
907
927
908
928
if old_rows != new_rows :
909
929
change = ModelChange (field .name , old_rows , new_rows )
0 commit comments