From 2f65a620c6af5faae859071eb2e1d2ee177bd5e5 Mon Sep 17 00:00:00 2001 From: Alan Zhu <2025azhu@tjhsst.edu> Date: Sat, 5 Oct 2024 01:44:06 -0400 Subject: [PATCH] feat: add announcement edit history --- intranet/apps/announcements/admin.py | 5 +- ...ouncement_historicalwarningannouncement.py | 72 +++++++++++++++++++ intranet/apps/announcements/models.py | 5 ++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 intranet/apps/announcements/migrations/0034_historicalannouncement_historicalwarningannouncement.py diff --git a/intranet/apps/announcements/admin.py b/intranet/apps/announcements/admin.py index a80e2268696..1232daaeaf6 100644 --- a/intranet/apps/announcements/admin.py +++ b/intranet/apps/announcements/admin.py @@ -1,9 +1,10 @@ from django.contrib import admin +from simple_history.admin import SimpleHistoryAdmin from .models import Announcement, WarningAnnouncement -class AnnouncementAdmin(admin.ModelAdmin): +class AnnouncementAdmin(SimpleHistoryAdmin): list_display = ("title", "user", "author", "activity", "added") list_filter = ("added", "updated", "activity") ordering = ("-added",) @@ -11,7 +12,7 @@ class AnnouncementAdmin(admin.ModelAdmin): search_fields = ("title", "content", "user__first_name", "user__last_name", "user__username") -class WarningAnnouncementAdmin(admin.ModelAdmin): +class WarningAnnouncementAdmin(SimpleHistoryAdmin): list_display = ("title", "content", "active") list_filter = ("active",) search_fields = ("title", "content") diff --git a/intranet/apps/announcements/migrations/0034_historicalannouncement_historicalwarningannouncement.py b/intranet/apps/announcements/migrations/0034_historicalannouncement_historicalwarningannouncement.py new file mode 100644 index 00000000000..30a9005aae9 --- /dev/null +++ b/intranet/apps/announcements/migrations/0034_historicalannouncement_historicalwarningannouncement.py @@ -0,0 +1,72 @@ +# Generated by Django 3.2.25 on 2024-10-05 05:34 + +import datetime +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +from django.utils.timezone import utc +import simple_history.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('eighth', '0070_eighthactivity_club_sponsors'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('announcements', '0033_announcement_activity'), + ] + + operations = [ + migrations.CreateModel( + name='HistoricalWarningAnnouncement', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('title', models.CharField(max_length=127)), + ('content', models.TextField(help_text='Content of the warning. You can use HTML here.')), + ('type', models.CharField(choices=[('dashboard', 'Dashboard Warning (displays on dashboard)'), ('login', 'Login Warning (displays on login page)'), ('dashboard_login', 'Dashboard and Login Warning (displays on dashboard and login pages)'), ('global', 'Global Warning (displays on all pages)')], default='dashboard', max_length=127)), + ('active', models.BooleanField(default=True, help_text='Whether or not to show the warning.')), + ('added', models.DateTimeField(blank=True, editable=False)), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField(db_index=True)), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'historical warning announcement', + 'verbose_name_plural': 'historical warning announcements', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': ('history_date', 'history_id'), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name='HistoricalAnnouncement', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('title', models.CharField(max_length=127)), + ('content', models.TextField()), + ('author', models.CharField(blank=True, max_length=63)), + ('added', models.DateTimeField(blank=True, editable=False)), + ('updated', models.DateTimeField(blank=True, editable=False)), + ('expiration_date', models.DateTimeField(default=datetime.datetime(3000, 1, 1, 5, 0, tzinfo=utc))), + ('notify_post', models.BooleanField(default=True)), + ('notify_email_all', models.BooleanField(default=False)), + ('pinned', models.BooleanField(default=False)), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField(db_index=True)), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('activity', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='eighth.eighthactivity')), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'historical announcement', + 'verbose_name_plural': 'historical announcements', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': ('history_date', 'history_id'), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + ] diff --git a/intranet/apps/announcements/models.py b/intranet/apps/announcements/models.py index 814a95c62ac..3a4cd45f155 100644 --- a/intranet/apps/announcements/models.py +++ b/intranet/apps/announcements/models.py @@ -6,6 +6,7 @@ from django.db import models from django.db.models import Manager, Q from django.utils import timezone +from simple_history.models import HistoricalRecords from ...utils.date import get_date_range_this_year, is_current_year from ...utils.deletion import set_historical_user @@ -120,6 +121,8 @@ class Announcement(models.Model): pinned = models.BooleanField(default=False) + history = HistoricalRecords() + def get_author(self) -> str: """Returns 'author' if it is set. Otherwise, returns the name of the user who created the announcement. @@ -294,6 +297,8 @@ class WarningAnnouncement(models.Model): active = models.BooleanField(default=True, help_text="Whether or not to show the warning.") added = models.DateTimeField(auto_now_add=True) + history = HistoricalRecords() + @property def show_on_dashboard(self): return self.type in ("dashboard", "dashboard_login") # global is not included. It will show on all pages and this logic isn't needed.