Skip to content

Commit 73800bb

Browse files
Abdullah AlaqeelMercymeIlya
authored andcommitted
feat: collect all models including auto created ones and excluding non-managed ones (jazzband#550)
feat: automatically register m2m fields for models when opting to auto register models
1 parent 5e8f856 commit 73800bb

File tree

4 files changed

+73
-5
lines changed

4 files changed

+73
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- feat: Added pre-log and post-log signals. ([#483](https://github.com/jazzband/django-auditlog/pull/483))
1717
- feat: Make timestamp in LogEntry overwritable. ([#476](https://github.com/jazzband/django-auditlog/pull/476))
1818
- feat: Support excluding field names globally when ```AUDITLOG_INCLUDE_ALL_MODELS``` is enabled. ([#498](https://github.com/jazzband/django-auditlog/pull/498))
19+
- feat: Improved auto model registration to include auto-created models and exclude non-managed models, and automatically register m2m fields for models. ([#550](https://github.com/jazzband/django-auditlog/pull/550))
1920

2021
#### Fixes
2122

auditlog/registry.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
)
1414

1515
from django.apps import apps
16-
from django.db.models import Model
16+
from django.db.models import ManyToManyField, Model
1717
from django.db.models.base import ModelBase
1818
from django.db.models.signals import (
1919
ModelSignal,
@@ -337,12 +337,28 @@ def register_from_settings(self):
337337
exclude_models = self._get_exclude_models(
338338
settings.AUDITLOG_EXCLUDE_TRACKING_MODELS
339339
)
340-
models = apps.get_models()
341340

342-
for model in models:
341+
for model in apps.get_models(include_auto_created=True):
343342
if model in exclude_models:
344343
continue
345-
self.register(model)
344+
345+
meta = model._meta
346+
if not meta.managed:
347+
continue
348+
349+
m2m_fields = [
350+
m.name for m in meta.get_fields() if isinstance(m, ManyToManyField)
351+
]
352+
353+
exclude_fields = [
354+
i.related_name
355+
for i in meta.related_objects
356+
if i.related_name and not i.related_model._meta.managed
357+
]
358+
359+
self.register(
360+
model=model, m2m_fields=m2m_fields, exclude_fields=exclude_fields
361+
)
346362

347363
self._register_models(settings.AUDITLOG_INCLUDE_TRACKING_MODELS)
348364

auditlog_tests/models.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,29 @@ class SerializeNaturalKeyRelatedModel(models.Model):
301301
history = AuditlogHistoryField(delete_related=False)
302302

303303

304+
class SimpleNonManagedModel(models.Model):
305+
"""
306+
A simple model with no special things going on.
307+
"""
308+
309+
text = models.TextField(blank=True)
310+
boolean = models.BooleanField(default=False)
311+
integer = models.IntegerField(blank=True, null=True)
312+
datetime = models.DateTimeField(auto_now=True)
313+
314+
history = AuditlogHistoryField()
315+
316+
def __str__(self):
317+
return self.text
318+
319+
class Meta:
320+
managed = False
321+
322+
323+
class AutoManyRelatedModel(models.Model):
324+
related = models.ManyToManyField(SimpleModel)
325+
326+
304327
auditlog.register(AltPrimaryKeyModel)
305328
auditlog.register(UUIDPrimaryKeyModel)
306329
auditlog.register(ProxyModel)

auditlog_tests/tests.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from auditlog_tests.models import (
3737
AdditionalDataIncludedModel,
3838
AltPrimaryKeyModel,
39+
AutoManyRelatedModel,
3940
CharfieldTextfieldModel,
4041
ChoicesFieldModel,
4142
DateTimeFieldModel,
@@ -55,6 +56,7 @@
5556
SimpleMappingModel,
5657
SimpleMaskedModel,
5758
SimpleModel,
59+
SimpleNonManagedModel,
5860
UUIDPrimaryKeyModel,
5961
)
6062

@@ -1136,7 +1138,7 @@ def test_register_models_register_app(self):
11361138

11371139
self.assertTrue(self.test_auditlog.contains(SimpleExcludeModel))
11381140
self.assertTrue(self.test_auditlog.contains(ChoicesFieldModel))
1139-
self.assertEqual(len(self.test_auditlog.get_models()), 23)
1141+
self.assertEqual(len(self.test_auditlog.get_models()), 25)
11401142

11411143
def test_register_models_register_model_with_attrs(self):
11421144
self.test_auditlog._register_models(
@@ -1330,6 +1332,32 @@ def test_registration_error_if_bad_serialize_params(self):
13301332
SimpleModel, serialize_kwargs={"fields": ["text", "integer"]}
13311333
)
13321334

1335+
@override_settings(AUDITLOG_INCLUDE_ALL_MODELS=True)
1336+
def test_register_from_settings_register_all_models_excluding_non_managed_models(
1337+
self,
1338+
):
1339+
self.test_auditlog.register_from_settings()
1340+
1341+
self.assertFalse(self.test_auditlog.contains(SimpleNonManagedModel))
1342+
1343+
@override_settings(AUDITLOG_INCLUDE_ALL_MODELS=True)
1344+
def test_register_from_settings_register_all_models_and_figure_out_m2m_fields(self):
1345+
self.test_auditlog.register_from_settings()
1346+
1347+
self.assertIn(
1348+
"related", self.test_auditlog._registry[AutoManyRelatedModel]["m2m_fields"]
1349+
)
1350+
1351+
@override_settings(AUDITLOG_INCLUDE_ALL_MODELS=True)
1352+
def test_register_from_settings_register_all_models_including_auto_created_models(
1353+
self,
1354+
):
1355+
self.test_auditlog.register_from_settings()
1356+
1357+
self.assertTrue(
1358+
self.test_auditlog.contains(AutoManyRelatedModel.related.through)
1359+
)
1360+
13331361

13341362
class ChoicesFieldModelTest(TestCase):
13351363
def setUp(self):

0 commit comments

Comments
 (0)