Following the instructions in the docs to subclass AbstractLogEntry to provide my own model
from django.db import models
from auditlog.models import AbstractLogEntry
class CustomLogEntryModel(AbstractLogEntry):
role = models.CharField(max_length=100, null=True, blank=True)
DATABASE_URL=postgresql:///example uv run manage.py makemigrations polls
Migrations for 'polls':
polls/migrations/0001_initial.py
+ Create model CustomLogEntryModel
After migrating and looking at my DB schema, there's both auditlog_logentry and polls_customlogentrymodel
+--------+----------------------------+-------+-------+
| Schema | Name | Type | Owner |
|--------+----------------------------+-------+-------|
| public | auditlog_logentry | table | jack |
.......................................................
| public | polls_customlogentrymodel | table | jack |
+--------+----------------------------+-------+-------+
This causes issues when trying to flush the database
$ DATABASE_URL=postgresql:///example uv run manage.py flush --no-input
CommandError: Database example couldn't be flushed. Possible reasons:
* The database isn't running or isn't configured correctly.
* At least one of the expected database tables doesn't exist.
* The SQL was invalid.
Hint: Look at the output of 'django-admin sqlflush'. That's the SQL this command wasn't able to run.
If we look at the output of sqlfush
DATABASE_URL=postgresql:///example uv run manage.py sqlflush
BEGIN;
TRUNCATE "django_session", "auth_user_groups", "auth_permission", "auth_group_permissions", "auth_group", "polls_customlogentrymodel", "auth_user_user_permissions", "django_content_type", "auth_user", "django_admin_log" RESTART IDENTITY;
COMMIT;
Running this within psql
jack@(none):example> BEGIN;
TRUNCATE "django_session", "auth_user_groups", "auth_permission", "auth_group_permissions", "auth_group", "polls_customlogentrymodel", "auth_user_user_permissions", "django_content_type", "a
uth_user", "django_admin_log" RESTART IDENTITY;
COMMIT;
You're about to run a destructive command.
Do you want to proceed? [y/N]: y
Your call!
BEGIN
cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "auditlog_logentry" references "django_content_type".
HINT: Truncate table "auditlog_logentry" at the same time, or use TRUNCATE ... CASCADE.
Time: 0.004s
jack@(none):example>
Django rightly thinks our audit log model is polls_customlogentrymodel, but the fact auditlog_logentry exists means we can no longer flush our DB because it still has a FK constraint with django_content_type.
My best guess is that we need to make the log model swappable with AUDIT_LOGENTRY_MODEL
|
class Migration(migrations.Migration): |
|
dependencies = [ |
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
|
("contenttypes", "0001_initial"), |
|
] |
|
|
|
operations = [ |
|
migrations.CreateModel( |
|
name="LogEntry", |
|
fields=[ |
|
( |
|
"id", |
|
models.AutoField( |
|
verbose_name="ID", |
|
serialize=False, |
|
auto_created=True, |
|
primary_key=True, |
|
), |
|
), |
|
("object_pk", models.TextField(verbose_name="object pk")), |
|
( |
|
"object_id", |
|
models.PositiveIntegerField( |
|
db_index=True, null=True, verbose_name="object id", blank=True |
|
), |
|
), |
|
("object_repr", models.TextField(verbose_name="object representation")), |
|
( |
|
"action", |
|
models.PositiveSmallIntegerField( |
|
verbose_name="action", |
|
choices=[(0, "create"), (1, "update"), (2, "delete")], |
|
), |
|
), |
|
( |
|
"changes", |
|
models.TextField(verbose_name="change message", blank=True), |
|
), |
|
( |
|
"timestamp", |
|
models.DateTimeField(auto_now_add=True, verbose_name="timestamp"), |
|
), |
|
( |
|
"actor", |
|
models.ForeignKey( |
|
related_name="+", |
|
on_delete=django.db.models.deletion.SET_NULL, |
|
verbose_name="actor", |
|
blank=True, |
|
to=settings.AUTH_USER_MODEL, |
|
null=True, |
|
), |
|
), |
|
( |
|
"content_type", |
|
models.ForeignKey( |
|
on_delete=django.db.models.deletion.CASCADE, |
|
related_name="+", |
|
verbose_name="content type", |
|
to="contenttypes.ContentType", |
|
), |
|
), |
|
], |
|
options={ |
|
"ordering": ["-timestamp"], |
|
"get_latest_by": "timestamp", |
|
"verbose_name": "log entry", |
|
"verbose_name_plural": "log entries", |
|
}, |
|
bases=(models.Model,), |
|
), |
|
] |
Following the instructions in the docs to subclass
AbstractLogEntryto provide my own modelAfter migrating and looking at my DB schema, there's both
auditlog_logentryandpolls_customlogentrymodelThis causes issues when trying to flush the database
If we look at the output of
sqlfushRunning this within
psqlDjango rightly thinks our audit log model is
polls_customlogentrymodel, but the factauditlog_logentryexists means we can no longer flush our DB because it still has a FK constraint withdjango_content_type.My best guess is that we need to make the log model swappable with
AUDIT_LOGENTRY_MODELdjango-auditlog/auditlog/migrations/0001_initial.py
Lines 6 to 77 in 3f255a0