From fbef114a444ff80a02123868c453a3ae630ed8ce Mon Sep 17 00:00:00 2001 From: Zaki Benaissa Date: Fri, 12 Jan 2024 18:18:36 +0100 Subject: [PATCH 1/3] Create ActivityLog model --- course/models.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/course/models.py b/course/models.py index 1337169..8e9247b 100644 --- a/course/models.py +++ b/course/models.py @@ -2,11 +2,13 @@ from django.db import models from django.urls import reverse from django.conf import settings from django.core.validators import FileExtensionValidator -from django.db.models.signals import pre_save +from django.db.models.signals import pre_save, post_save, post_delete from django.db.models import Q +from django.dispatch import receiver # project import from .utils import * +from core.models import ActivityLog YEARS = ( (1, "1"), @@ -62,6 +64,21 @@ class Program(models.Model): return reverse("program_detail", kwargs={"pk": self.pk}) +@receiver(post_save, sender=Program) +def log_save(sender, instance, created, **kwargs): + verb = "created" if created else "updated" + ActivityLog.objects.create( + message=f"The program '{instance.title}' has been {verb}." + ) + + +@receiver(post_delete, sender=Program) +def log_delete(sender, instance, **kwargs): + ActivityLog.objects.create( + message=f"The program '{instance.title}' has been deleted." + ) + + class CourseManager(models.Manager): def search(self, query=None): queryset = self.get_queryset() @@ -118,6 +135,21 @@ def course_pre_save_receiver(sender, instance, *args, **kwargs): pre_save.connect(course_pre_save_receiver, sender=Course) +@receiver(post_save, sender=Course) +def log_save(sender, instance, created, **kwargs): + verb = "created" if created else "updated" + ActivityLog.objects.create( + message=f"The course '{instance.title}' has been {verb}." + ) + + +@receiver(post_delete, sender=Course) +def log_delete(sender, instance, **kwargs): + ActivityLog.objects.create( + message=f"The course '{instance.title}' has been deleted." + ) + + class CourseAllocation(models.Model): lecturer = models.ForeignKey( settings.AUTH_USER_MODEL, @@ -184,6 +216,25 @@ class Upload(models.Model): super().delete(*args, **kwargs) +@receiver(post_save, sender=Upload) +def log_save(sender, instance, created, **kwargs): + if created: + ActivityLog.objects.create( + message=f"The file '{instance.title}' has been uploaded to the course '{instance.course}'." + ) + else: + ActivityLog.objects.create( + message=f"The file '{instance.title}' of the course '{instance.course}' has been updated." + ) + + +@receiver(post_delete, sender=Upload) +def log_delete(sender, instance, **kwargs): + ActivityLog.objects.create( + message=f"The file '{instance.title}' of the course '{instance.course}' has been deleted." + ) + + class UploadVideo(models.Model): title = models.CharField(max_length=100) slug = models.SlugField(blank=True, unique=True) @@ -218,6 +269,25 @@ def video_pre_save_receiver(sender, instance, *args, **kwargs): pre_save.connect(video_pre_save_receiver, sender=UploadVideo) +@receiver(post_save, sender=UploadVideo) +def log_save(sender, instance, created, **kwargs): + if created: + ActivityLog.objects.create( + message=f"The video '{instance.title}' has been uploaded to the course {instance.course}." + ) + else: + ActivityLog.objects.create( + message=f"The video '{instance.title}' of the course '{instance.course}' has been updated." + ) + + +@receiver(post_delete, sender=UploadVideo) +def log_delete(sender, instance, **kwargs): + ActivityLog.objects.create( + message=f"The video '{instance.title}' of the course '{instance.course}' has been deleted." + ) + + class CourseOffer(models.Model): """NOTE: Only department head can offer semester courses""" From 61afcc7971a7d8d4d191a6821de28d6ee5edc78d Mon Sep 17 00:00:00 2001 From: Zaki Benaissa Date: Fri, 12 Jan 2024 18:19:29 +0100 Subject: [PATCH 2/3] Log CUD operations on the course app's models --- core/migrations/0005_activitylog.py | 21 +++++++++++++++++++++ core/models.py | 8 ++++++++ 2 files changed, 29 insertions(+) create mode 100644 core/migrations/0005_activitylog.py diff --git a/core/migrations/0005_activitylog.py b/core/migrations/0005_activitylog.py new file mode 100644 index 0000000..3fee87b --- /dev/null +++ b/core/migrations/0005_activitylog.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.8 on 2024-01-12 15:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_alter_newsandevents_id_alter_semester_id_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='ActivityLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('message', models.TextField()), + ('created_at', models.DateTimeField(auto_now=True)), + ], + ), + ] diff --git a/core/models.py b/core/models.py index a13ac44..b78f84e 100644 --- a/core/models.py +++ b/core/models.py @@ -84,3 +84,11 @@ class Semester(models.Model): def __str__(self): return self.semester + + +class ActivityLog(models.Model): + message = models.TextField() + created_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"[{self.created_at}]{self.message}" From 9e09dad1b8861e61c30d8642332c8f7b2c944dde Mon Sep 17 00:00:00 2001 From: Zaki Benaissa Date: Fri, 12 Jan 2024 18:24:53 +0100 Subject: [PATCH 3/3] Display latest ActivityLogs in the dashboard --- core/views.py | 2 ++ course/models.py | 16 ++++------------ templates/core/dashboard.html | 15 ++++++--------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/core/views.py b/core/views.py index ea40adf..e2da465 100644 --- a/core/views.py +++ b/core/views.py @@ -298,9 +298,11 @@ def semester_delete_view(request, pk): @login_required @admin_required def dashboard_view(request): + logs = ActivityLog.objects.all().order_by("-created_at")[:10] context = { "student_count": User.get_student_count(), "lecturer_count": User.get_lecturer_count(), "superuser_count": User.get_superuser_count(), + "logs": logs, } return render(request, "core/dashboard.html", context) diff --git a/course/models.py b/course/models.py index 8e9247b..d516dc9 100644 --- a/course/models.py +++ b/course/models.py @@ -67,16 +67,12 @@ class Program(models.Model): @receiver(post_save, sender=Program) def log_save(sender, instance, created, **kwargs): verb = "created" if created else "updated" - ActivityLog.objects.create( - message=f"The program '{instance.title}' has been {verb}." - ) + ActivityLog.objects.create(message=f"The program '{instance}' has been {verb}.") @receiver(post_delete, sender=Program) def log_delete(sender, instance, **kwargs): - ActivityLog.objects.create( - message=f"The program '{instance.title}' has been deleted." - ) + ActivityLog.objects.create(message=f"The program '{instance}' has been deleted.") class CourseManager(models.Manager): @@ -138,16 +134,12 @@ pre_save.connect(course_pre_save_receiver, sender=Course) @receiver(post_save, sender=Course) def log_save(sender, instance, created, **kwargs): verb = "created" if created else "updated" - ActivityLog.objects.create( - message=f"The course '{instance.title}' has been {verb}." - ) + ActivityLog.objects.create(message=f"The course '{instance}' has been {verb}.") @receiver(post_delete, sender=Course) def log_delete(sender, instance, **kwargs): - ActivityLog.objects.create( - message=f"The course '{instance.title}' has been deleted." - ) + ActivityLog.objects.create(message=f"The course '{instance}' has been deleted.") class CourseAllocation(models.Model): diff --git a/templates/core/dashboard.html b/templates/core/dashboard.html index da06ecb..bde9eef 100644 --- a/templates/core/dashboard.html +++ b/templates/core/dashboard.html @@ -275,16 +275,13 @@
-
Overall activities
+
Latest activities
    -
  • Created a survey of something
  • -
  • Added new admin user
  • -
  • Deleted 1 video from CSE course
  • -
  • New documentation attached for Arch
  • -
  • Lorem ipsum dolor sit amet consectetur adipisicing elit.
  • -
  • Veniam magnam reiciendis modi explicabo sed aliquid natus
  • -
  • molestias corrupti suscipit similique ex adipisci praesentium
  • -
  • sint dolore, quo quibusdam ea, neque cupiditate.
  • + {% for log in logs %} +
  • {{ log.message }} - {{ log.created_at }}
  • + {% empty %} + No recent activity + {% endfor %}