From e2d7670c9a3d7b2d637c80f4cd99a648b83e5772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9ni?= Date: Tue, 5 Sep 2023 18:20:16 +0200 Subject: [PATCH] feat: m2m_fields accepts field names (#1243) --- CHANGES.rst | 1 + docs/historical_model.rst | 9 ++++++--- simple_history/models.py | 5 ++++- simple_history/tests/models.py | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index fbe4f979c..15fd8958f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,7 @@ Changes Unreleased ---------- +- Allow ``HistoricalRecords.m2m_fields`` as str 3.4.0 (2023-08-18) ------------------ diff --git a/docs/historical_model.rst b/docs/historical_model.rst index ee2c47e56..45739ec10 100644 --- a/docs/historical_model.rst +++ b/docs/historical_model.rst @@ -469,9 +469,12 @@ If you want to track many to many relationships, you need to define them explici This will create a historical intermediate model that tracks each relational change between `Poll` and `Category`. -You may also define these fields in a model attribute (by default on `_history_m2m_fields`). -This is mainly used for inherited models. You can override the attribute name by setting -your own `m2m_fields_model_field_name` argument on the `HistoricalRecord` instance. +You may use either the name of the field or the field instance itself. + +You may also define these fields in a class attribute (by default on `_history_m2m_fields`). +This is mainly used by inherited models not declaring their own `HistoricalRecord`. +You can override the attribute name by setting your own `m2m_fields_model_field_name` +argument on the `HistoricalRecord` instance. You will see the many to many changes when diffing between two historical records: diff --git a/simple_history/models.py b/simple_history/models.py index 4ad5c2e9c..6dc4db9e8 100644 --- a/simple_history/models.py +++ b/simple_history/models.py @@ -768,7 +768,10 @@ def get_m2m_fields_from_model(self, model): m2m_fields.update(getattr(model, self.m2m_fields_model_field_name)) except AttributeError: pass - return [getattr(model, field.name).field for field in m2m_fields] + field_names = [ + field if isinstance(field, str) else field.name for field in m2m_fields + ] + return [getattr(model, field_name).field for field_name in field_names] def transform_field(field): diff --git a/simple_history/tests/models.py b/simple_history/tests/models.py index 5c1da32ad..f1c89ac3b 100644 --- a/simple_history/tests/models.py +++ b/simple_history/tests/models.py @@ -190,7 +190,7 @@ class Meta: class PollChildBookWithManyToMany(PollParentWithManyToMany): books = models.ManyToManyField("Book", related_name="books_poll_child") - _history_m2m_fields = [books] + _history_m2m_fields = ["books"] class PollChildRestaurantWithManyToMany(PollParentWithManyToMany):