From 77ef852706ccfa8523f8de98e886fc9097e252d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Gon=C3=A7alves?= Date: Mon, 7 Mar 2022 10:22:08 -0300 Subject: [PATCH] enable use of replica database (#359) * enable use of replica database When you use replica database the django-auditlog try to write in the same database where object was read (replica). But this is a read only database and crash the application. This changes saves always in the default database. If you want to save in multiple databases or in a special one use `DATABASE_ROUTERS` to configure it. Co-authored-by: Hasan Ramezani --- CHANGELOG.md | 6 ++++++ auditlog/models.py | 8 +------- auditlog_tests/tests.py | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd7c216..767c820 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes +#### Improvements +- feat: enable use of replica database (delegating the choice to `DATABASES_ROUTER`) ([#359](https://github.com/jazzband/django-auditlog/pull/359)) + +#### Important notes +- LogEntry no longer save to same database instance is using + ## 1.0.0 (2022-01-24) ### Final diff --git a/auditlog/models.py b/auditlog/models.py index 606c604..a50ead7 100644 --- a/auditlog/models.py +++ b/auditlog/models.py @@ -67,13 +67,7 @@ class LogEntryManager(models.Manager): content_type=kwargs.get("content_type"), object_pk=kwargs.get("object_pk", ""), ).delete() - # save LogEntry to same database instance is using - db = instance._state.db - return ( - self.create(**kwargs) - if db is None or db == "" - else self.using(db).create(**kwargs) - ) + return self.create(**kwargs) return None def get_for_object(self, instance): diff --git a/auditlog_tests/tests.py b/auditlog_tests/tests.py index fc96d8e..45917a6 100644 --- a/auditlog_tests/tests.py +++ b/auditlog_tests/tests.py @@ -1,4 +1,5 @@ import datetime +import json import django from dateutil.tz import gettz @@ -11,6 +12,7 @@ from django.http import HttpResponse from django.test import RequestFactory, TestCase from django.utils import dateformat, formats, timezone +from auditlog.diff import model_instance_diff from auditlog.middleware import AuditlogMiddleware from auditlog.models import LogEntry from auditlog.registry import auditlog @@ -149,6 +151,24 @@ class SimpleModelTest(TestCase): self.setUp() self.test_create() + def test_create_log_to_object_from_other_database(self): + msg = "The log should not try to write to the same database as the object" + + instance = self.obj + # simulate object obtained from a different database (read only) + instance._state.db = "replica" + + changes = model_instance_diff(None, instance) + + log_entry = LogEntry.objects.log_create( + instance, + action=LogEntry.Action.CREATE, + changes=json.dumps(changes), + ) + self.assertEqual( + log_entry._state.db, "default", msg=msg + ) # must be created in default database + class AltPrimaryKeyModelTest(SimpleModelTest): def setUp(self):