feat: collect all models including auto created ones and excluding non-managed ones (#550)

feat: automatically register m2m fields for models when opting to auto register models
This commit is contained in:
Abdullah Alaqeel 2023-08-09 18:11:21 +03:00 committed by GitHub
parent 3dc4f1a02d
commit f2591e420b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 5 deletions

View file

@ -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

View file

@ -13,7 +13,7 @@ from typing import (
)
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,
@ -336,12 +336,28 @@ class AuditlogModelRegistry:
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)

View file

@ -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)

View file

@ -36,6 +36,7 @@ from auditlog_tests.fixtures.custom_get_cid import get_cid as custom_get_cid
from auditlog_tests.models import (
AdditionalDataIncludedModel,
AltPrimaryKeyModel,
AutoManyRelatedModel,
CharfieldTextfieldModel,
ChoicesFieldModel,
DateTimeFieldModel,
@ -55,6 +56,7 @@ from auditlog_tests.models import (
SimpleMappingModel,
SimpleMaskedModel,
SimpleModel,
SimpleNonManagedModel,
UUIDPrimaryKeyModel,
)
@ -1136,7 +1138,7 @@ class RegisterModelSettingsTest(TestCase):
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(
@ -1330,6 +1332,32 @@ class RegisterModelSettingsTest(TestCase):
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):