Refactor model imports and update admin classes to use pghistory for historical tracking; replace HistoricalModel with TrackedModel in relevant models

This commit is contained in:
pacnpal
2025-02-09 11:20:40 -05:00
parent 52cb51cb14
commit 64d9943d86
24 changed files with 1729 additions and 137 deletions

View File

@@ -3,7 +3,6 @@ from django.contrib.admin import AdminSite
from django.utils.html import format_html
from django.urls import reverse
from django.utils.safestring import mark_safe
import pghistory
from .models import EditSubmission, PhotoSubmission
class ModerationAdminSite(AdminSite):
@@ -77,7 +76,7 @@ class PhotoSubmissionAdmin(admin.ModelAdmin):
obj.reject(request.user, obj.notes)
super().save_model(request, obj, form, change)
class HistoryAdmin(admin.ModelAdmin):
class HistoryEventAdmin(admin.ModelAdmin):
"""Admin interface for viewing model history events"""
list_display = ['pgh_label', 'pgh_created_at', 'get_object_link', 'get_context']
list_filter = ['pgh_label', 'pgh_created_at']
@@ -106,4 +105,6 @@ class HistoryAdmin(admin.ModelAdmin):
# Register with moderation site only
moderation_site.register(EditSubmission, EditSubmissionAdmin)
moderation_site.register(PhotoSubmission, PhotoSubmissionAdmin)
moderation_site.register(pghistory.models.Event, HistoryAdmin)
# We will register concrete event models as they are created during migrations
# Example: moderation_site.register(DesignerEvent, HistoryEventAdmin)

View File

@@ -0,0 +1,305 @@
# Generated by Django 5.1.4 on 2025-02-09 15:24
import django.db.models.deletion
import pgtrigger.compiler
import pgtrigger.migrations
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("contenttypes", "0002_remove_content_type_name"),
("moderation", "0004_add_moderator_changes"),
("pghistory", "0006_delete_aggregateevent"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="EditSubmissionEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("object_id", models.PositiveIntegerField(blank=True, null=True)),
(
"submission_type",
models.CharField(
choices=[("EDIT", "Edit Existing"), ("CREATE", "Create New")],
default="EDIT",
max_length=10,
),
),
(
"changes",
models.JSONField(
help_text="JSON representation of the changes or new object data"
),
),
(
"moderator_changes",
models.JSONField(
blank=True,
help_text="Moderator's edited version of the changes before approval",
null=True,
),
),
(
"reason",
models.TextField(help_text="Why this edit/addition is needed"),
),
(
"source",
models.TextField(
blank=True, help_text="Source of information (if applicable)"
),
),
(
"status",
models.CharField(
choices=[
("PENDING", "Pending"),
("APPROVED", "Approved"),
("REJECTED", "Rejected"),
("ESCALATED", "Escalated"),
],
default="PENDING",
max_length=20,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("handled_at", models.DateTimeField(blank=True, null=True)),
(
"notes",
models.TextField(
blank=True,
help_text="Notes from the moderator about this submission",
),
),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="PhotoSubmissionEvent",
fields=[
("pgh_id", models.AutoField(primary_key=True, serialize=False)),
("pgh_created_at", models.DateTimeField(auto_now_add=True)),
("pgh_label", models.TextField(help_text="The event label.")),
("id", models.BigIntegerField()),
("object_id", models.PositiveIntegerField()),
("photo", models.ImageField(upload_to="submissions/photos/")),
("caption", models.CharField(blank=True, max_length=255)),
("date_taken", models.DateField(blank=True, null=True)),
(
"status",
models.CharField(
choices=[
("PENDING", "Pending"),
("APPROVED", "Approved"),
("REJECTED", "Rejected"),
("ESCALATED", "Escalated"),
],
default="PENDING",
max_length=20,
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("handled_at", models.DateTimeField(blank=True, null=True)),
(
"notes",
models.TextField(
blank=True,
help_text="Notes from the moderator about this photo submission",
),
),
],
options={
"abstract": False,
},
),
migrations.AlterField(
model_name="editsubmission",
name="id",
field=models.BigAutoField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name="photosubmission",
name="id",
field=models.BigAutoField(primary_key=True, serialize=False),
),
pgtrigger.migrations.AddTrigger(
model_name="editsubmission",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "moderation_editsubmissionevent" ("changes", "content_type_id", "created_at", "handled_at", "handled_by_id", "id", "moderator_changes", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "reason", "source", "status", "submission_type", "user_id") VALUES (NEW."changes", NEW."content_type_id", NEW."created_at", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."moderator_changes", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."reason", NEW."source", NEW."status", NEW."submission_type", NEW."user_id"); RETURN NULL;',
hash="616bbed667e6f8a1b23dfa39b5b3fd0b3bc0b43d",
operation="INSERT",
pgid="pgtrigger_insert_insert_2c796",
table="moderation_editsubmission",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="editsubmission",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "moderation_editsubmissionevent" ("changes", "content_type_id", "created_at", "handled_at", "handled_by_id", "id", "moderator_changes", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "reason", "source", "status", "submission_type", "user_id") VALUES (NEW."changes", NEW."content_type_id", NEW."created_at", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."moderator_changes", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."reason", NEW."source", NEW."status", NEW."submission_type", NEW."user_id"); RETURN NULL;',
hash="76c447d8cfeced3bb1893e2d900c97bb05a9f028",
operation="UPDATE",
pgid="pgtrigger_update_update_ab38f",
table="moderation_editsubmission",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="photosubmission",
trigger=pgtrigger.compiler.Trigger(
name="insert_insert",
sql=pgtrigger.compiler.UpsertTriggerSql(
func='INSERT INTO "moderation_photosubmissionevent" ("caption", "content_type_id", "created_at", "date_taken", "handled_at", "handled_by_id", "id", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "photo", "status", "user_id") VALUES (NEW."caption", NEW."content_type_id", NEW."created_at", NEW."date_taken", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'insert\', NEW."id", NEW."photo", NEW."status", NEW."user_id"); RETURN NULL;',
hash="ea6563a26e5875de544fa270751df4f48003a4c0",
operation="INSERT",
pgid="pgtrigger_insert_insert_62865",
table="moderation_photosubmission",
when="AFTER",
),
),
),
pgtrigger.migrations.AddTrigger(
model_name="photosubmission",
trigger=pgtrigger.compiler.Trigger(
name="update_update",
sql=pgtrigger.compiler.UpsertTriggerSql(
condition="WHEN (OLD.* IS DISTINCT FROM NEW.*)",
func='INSERT INTO "moderation_photosubmissionevent" ("caption", "content_type_id", "created_at", "date_taken", "handled_at", "handled_by_id", "id", "notes", "object_id", "pgh_context_id", "pgh_created_at", "pgh_label", "pgh_obj_id", "photo", "status", "user_id") VALUES (NEW."caption", NEW."content_type_id", NEW."created_at", NEW."date_taken", NEW."handled_at", NEW."handled_by_id", NEW."id", NEW."notes", NEW."object_id", _pgh_attach_context(), NOW(), \'update\', NEW."id", NEW."photo", NEW."status", NEW."user_id"); RETURN NULL;',
hash="64f35eedbad17d4060eaeab7f2bd944620465591",
operation="UPDATE",
pgid="pgtrigger_update_update_9c311",
table="moderation_photosubmission",
when="AFTER",
),
),
),
migrations.AddField(
model_name="editsubmissionevent",
name="content_type",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="contenttypes.contenttype",
),
),
migrations.AddField(
model_name="editsubmissionevent",
name="handled_by",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="editsubmissionevent",
name="pgh_context",
field=models.ForeignKey(
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="pghistory.context",
),
),
migrations.AddField(
model_name="editsubmissionevent",
name="pgh_obj",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="events",
to="moderation.editsubmission",
),
),
migrations.AddField(
model_name="editsubmissionevent",
name="user",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="photosubmissionevent",
name="content_type",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to="contenttypes.contenttype",
),
),
migrations.AddField(
model_name="photosubmissionevent",
name="handled_by",
field=models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="photosubmissionevent",
name="pgh_context",
field=models.ForeignKey(
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="pghistory.context",
),
),
migrations.AddField(
model_name="photosubmissionevent",
name="pgh_obj",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="events",
to="moderation.photosubmission",
),
),
migrations.AddField(
model_name="photosubmissionevent",
name="user",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
related_query_name="+",
to=settings.AUTH_USER_MODEL,
),
),
]

View File

@@ -10,12 +10,12 @@ from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import AnonymousUser
from django.utils.text import slugify
import pghistory
from core.models import HistoricalModel
from history_tracking.models import TrackedModel
UserType = Union[AbstractBaseUser, AnonymousUser]
@pghistory.track() # Track all changes by default
class EditSubmission(HistoricalModel):
class EditSubmission(TrackedModel):
STATUS_CHOICES = [
("PENDING", "Pending"),
("APPROVED", "Approved"),
@@ -199,7 +199,7 @@ class EditSubmission(HistoricalModel):
self.save()
@pghistory.track() # Track all changes by default
class PhotoSubmission(HistoricalModel):
class PhotoSubmission(TrackedModel):
STATUS_CHOICES = [
("PENDING", "Pending"),
("APPROVED", "Approved"),