Skip to content

Commit

Permalink
feat: collect all models including auto created ones and excluding no…
Browse files Browse the repository at this point in the history
…n-managed ones (#550)

feat: automatically register m2m fields for models when opting to auto register models
  • Loading branch information
aqeelat committed Aug 9, 2023
1 parent 3dc4f1a commit f2591e4
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- feat: Added pre-log and post-log signals. ([#483](https://github.com/jazzband/django-auditlog/pull/483))
- feat: Make timestamp in LogEntry overwritable. ([#476](https://github.com/jazzband/django-auditlog/pull/476))
- feat: Support excluding field names globally when ```AUDITLOG_INCLUDE_ALL_MODELS``` is enabled. ([#498](https://github.com/jazzband/django-auditlog/pull/498))
- 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))

#### Fixes

Expand Down
24 changes: 20 additions & 4 deletions auditlog/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
)

from django.apps import apps
from django.db.models import Model
from django.db.models import ManyToManyField, Model
from django.db.models.base import ModelBase
from django.db.models.signals import (
ModelSignal,
Expand Down Expand Up @@ -336,12 +336,28 @@ def register_from_settings(self):
exclude_models = self._get_exclude_models(
settings.AUDITLOG_EXCLUDE_TRACKING_MODELS
)
models = apps.get_models()

for model in models:
for model in apps.get_models(include_auto_created=True):
if model in exclude_models:
continue
self.register(model)

meta = model._meta
if not meta.managed:
continue

m2m_fields = [
m.name for m in meta.get_fields() if isinstance(m, ManyToManyField)
]

exclude_fields = [
i.related_name
for i in meta.related_objects
if i.related_name and not i.related_model._meta.managed
]

self.register(
model=model, m2m_fields=m2m_fields, exclude_fields=exclude_fields
)

self._register_models(settings.AUDITLOG_INCLUDE_TRACKING_MODELS)

Expand Down
23 changes: 23 additions & 0 deletions auditlog_tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,29 @@ class SerializeNaturalKeyRelatedModel(models.Model):
history = AuditlogHistoryField(delete_related=False)


class SimpleNonManagedModel(models.Model):
"""
A simple model with no special things going on.
"""

text = models.TextField(blank=True)
boolean = models.BooleanField(default=False)
integer = models.IntegerField(blank=True, null=True)
datetime = models.DateTimeField(auto_now=True)

history = AuditlogHistoryField()

def __str__(self):
return self.text

class Meta:
managed = False


class AutoManyRelatedModel(models.Model):
related = models.ManyToManyField(SimpleModel)


auditlog.register(AltPrimaryKeyModel)
auditlog.register(UUIDPrimaryKeyModel)
auditlog.register(ProxyModel)
Expand Down
30 changes: 29 additions & 1 deletion auditlog_tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from auditlog_tests.models import (
AdditionalDataIncludedModel,
AltPrimaryKeyModel,
AutoManyRelatedModel,
CharfieldTextfieldModel,
ChoicesFieldModel,
DateTimeFieldModel,
Expand All @@ -55,6 +56,7 @@
SimpleMappingModel,
SimpleMaskedModel,
SimpleModel,
SimpleNonManagedModel,
UUIDPrimaryKeyModel,
)

Expand Down Expand Up @@ -1136,7 +1138,7 @@ def test_register_models_register_app(self):

self.assertTrue(self.test_auditlog.contains(SimpleExcludeModel))
self.assertTrue(self.test_auditlog.contains(ChoicesFieldModel))
self.assertEqual(len(self.test_auditlog.get_models()), 23)
self.assertEqual(len(self.test_auditlog.get_models()), 25)

def test_register_models_register_model_with_attrs(self):
self.test_auditlog._register_models(
Expand Down Expand Up @@ -1330,6 +1332,32 @@ def test_registration_error_if_bad_serialize_params(self):
SimpleModel, serialize_kwargs={"fields": ["text", "integer"]}
)

@override_settings(AUDITLOG_INCLUDE_ALL_MODELS=True)
def test_register_from_settings_register_all_models_excluding_non_managed_models(
self,
):
self.test_auditlog.register_from_settings()

self.assertFalse(self.test_auditlog.contains(SimpleNonManagedModel))

@override_settings(AUDITLOG_INCLUDE_ALL_MODELS=True)
def test_register_from_settings_register_all_models_and_figure_out_m2m_fields(self):
self.test_auditlog.register_from_settings()

self.assertIn(
"related", self.test_auditlog._registry[AutoManyRelatedModel]["m2m_fields"]
)

@override_settings(AUDITLOG_INCLUDE_ALL_MODELS=True)
def test_register_from_settings_register_all_models_including_auto_created_models(
self,
):
self.test_auditlog.register_from_settings()

self.assertTrue(
self.test_auditlog.contains(AutoManyRelatedModel.related.through)
)


class ChoicesFieldModelTest(TestCase):
def setUp(self):
Expand Down

0 comments on commit f2591e4

Please sign in to comment.