Use recommended manager (#705)

See https://docs.djangoproject.com/en/5.1/topics/db/managers/#default-managers
This commit is contained in:
sebastianmanger 2025-03-11 15:32:52 +01:00 committed by GitHub
parent de650b09c7
commit 939dd9b298
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 47 additions and 5 deletions

View file

@ -19,6 +19,7 @@ via `AUDITLOG_MASK_TRACKING_FIELDS` setting. ([#702](https://github.com/jazzband
- fix: Use sender instead of receiver for `m2m_changed` signal ID to prevent duplicate entries for models that share a related model. ([#686](https://github.com/jazzband/django-auditlog/pull/686))
- Fixed a problem when setting `Value(None)` in `JSONField` ([#646](https://github.com/jazzband/django-auditlog/pull/646))
- Fixed a problem when setting `django.db.models.functions.Now()` in `DateTimeField` ([#635](https://github.com/jazzband/django-auditlog/pull/635))
- Use the [default manager](https://docs.djangoproject.com/en/5.1/topics/db/managers/#default-managers) instead of `objects` to support custom model managers. ([#705](https://github.com/jazzband/django-auditlog/pull/705))
## 3.0.0 (2024-04-12)

View file

@ -542,7 +542,7 @@ class LogEntry(models.Model):
return value
# Attempt to return the string representation of the object
try:
return smart_str(field.related_model.objects.get(pk=pk_value))
return smart_str(field.related_model._default_manager.get(pk=pk_value))
# ObjectDoesNotExist will be raised if the object was deleted.
except ObjectDoesNotExist:
return f"Deleted '{field.related_model.__name__}' ({value})"

View file

@ -55,7 +55,7 @@ def log_update(sender, instance, **kwargs):
"""
if not instance._state.adding:
update_fields = kwargs.get("update_fields", None)
old = sender.objects.filter(pk=instance.pk).first()
old = sender._default_manager.filter(pk=instance.pk).first()
_create_log_entry(
action=LogEntry.Action.UPDATE,
instance=instance,
@ -156,9 +156,11 @@ def make_log_m2m_changes(field_name):
return
if action == "post_clear":
changed_queryset = kwargs["model"].objects.all()
changed_queryset = kwargs["model"]._default_manager.all()
else:
changed_queryset = kwargs["model"].objects.filter(pk__in=kwargs["pk_set"])
changed_queryset = kwargs["model"]._default_manager.filter(
pk__in=kwargs["pk_set"]
)
if action in ["post_add"]:
LogEntry.objects.log_m2m_changes(

View file

@ -407,6 +407,19 @@ class SimpleNonManagedModel(models.Model):
managed = False
class SecretManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(is_secret=False)
@auditlog.register()
class SwappedManagerModel(models.Model):
is_secret = models.BooleanField(default=False)
name = models.CharField(max_length=255)
objects = SecretManager()
class AutoManyRelatedModel(models.Model):
related = models.ManyToManyField(SimpleModel)

View file

@ -64,6 +64,7 @@ from auditlog_tests.models import (
SimpleMaskedModel,
SimpleModel,
SimpleNonManagedModel,
SwappedManagerModel,
UUIDPrimaryKeyModel,
)
@ -1270,7 +1271,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()), 31)
self.assertEqual(len(self.test_auditlog.get_models()), 32)
def test_register_models_register_model_with_attrs(self):
self.test_auditlog._register_models(
@ -2828,3 +2829,28 @@ class MissingModelTest(TestCase):
history = self.obj.history.latest()
self.assertEqual(history.changes_dict["text"][1], self.obj.text)
self.assertEqual(history.changes_display_dict["text"][1], self.obj.text)
class ModelManagerTest(TestCase):
"""
This does not directly assert the configured manager, but its behaviour.
The "secret" object should not be accessible, as the queryset is overridden.
"""
def setUp(self):
self.secret = SwappedManagerModel.objects.create(is_secret=True, name="Secret")
self.public = SwappedManagerModel.objects.create(is_secret=False, name="Public")
def test_update_secret(self):
self.secret.name = "Updated"
self.secret.save()
log = LogEntry.objects.get_for_object(self.secret).first()
self.assertEqual(log.action, LogEntry.Action.UPDATE)
self.assertEqual(log.changes_dict["name"], ["None", "Updated"])
def test_update_public(self):
self.public.name = "Updated"
self.public.save()
log = LogEntry.objects.get_for_object(self.public).first()
self.assertEqual(log.action, LogEntry.Action.UPDATE)
self.assertEqual(log.changes_dict["name"], ["Public", "Updated"])