Skip to content

Commit 78bcd0e

Browse files
authored
Use django builtin for determining through field name (#1218)
Fixes #1126
1 parent 4b22c58 commit 78bcd0e

File tree

5 files changed

+22
-1
lines changed

5 files changed

+22
-1
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Authors
9090
- Lucas Wiman
9191
- Maciej "RooTer" Urbański
9292
- Marcelo Canina (`marcanuy <https://github.com/marcanuy>`_)
93+
- Marco Sirabella
9394
- Mark Davidoff
9495
- Martin Bachwerk
9596
- Marty Alchin

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Unreleased
2424
``HistoricalRecords.context.request``) under some circumstances (gh-1188)
2525
- Made ``HistoryRequestMiddleware`` async-capable (gh-1209)
2626
- Fixed error when setting ``table_name`` with ``inherit=True`` (gh-1195)
27+
- Fixed ``FieldError`` when creating historical records for many-to-many fields with
28+
``to="self"`` (gh-1218)
2729

2830
3.3.0 (2023-03-08)
2931
------------------

simple_history/models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,8 @@ def create_historical_record_m2ms(self, history_instance, instance):
670670

671671
insert_rows = []
672672

673-
through_field_name = type(original_instance).__name__.lower()
673+
# `m2m_field_name()` is part of Django's internal API
674+
through_field_name = field.m2m_field_name()
674675

675676
rows = through_model.objects.filter(**{through_field_name: instance})
676677

simple_history/tests/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ class PollChildRestaurantWithManyToMany(PollParentWithManyToMany):
200200
_history_m2m_fields = [restaurants]
201201

202202

203+
class PollWithSelfManyToMany(models.Model):
204+
relations = models.ManyToManyField("self")
205+
history = HistoricalRecords(m2m_fields=[relations])
206+
207+
203208
class CustomAttrNameForeignKey(models.ForeignKey):
204209
def __init__(self, *args, **kwargs):
205210
self.attr_name = kwargs.pop("attr_name", None)

simple_history/tests/tests/test_models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
PollWithManyToManyCustomHistoryID,
104104
PollWithManyToManyWithIPAddress,
105105
PollWithNonEditableField,
106+
PollWithSelfManyToMany,
106107
PollWithSeveralManyToMany,
107108
Province,
108109
Restaurant,
@@ -1869,6 +1870,17 @@ def test_separation(self):
18691870
self.assertEqual(add.restaurants.all().count(), 0)
18701871
self.assertEqual(add.places.all().count(), 0)
18711872

1873+
def test_self_field(self):
1874+
poll1 = PollWithSelfManyToMany.objects.create()
1875+
poll2 = PollWithSelfManyToMany.objects.create()
1876+
1877+
self.assertEqual(poll1.history.all().count(), 1)
1878+
1879+
poll1.relations.add(poll2)
1880+
self.assertIn(poll2, poll1.relations.all())
1881+
1882+
self.assertEqual(poll1.history.all().count(), 2)
1883+
18721884

18731885
class ManyToManyWithSignalsTest(TestCase):
18741886
def setUp(self):

0 commit comments

Comments
 (0)