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 <hasan.r67@gmail.com>
This commit is contained in:
Samuel Gonçalves 2022-03-07 10:22:08 -03:00 committed by GitHub
parent 665217d32f
commit 77ef852706
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 7 deletions

View file

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

View file

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

View file

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