Skip to content
Snippets Groups Projects
Verified Commit f0f882a2 authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Implement created_at and updated_at as properties fro CRUDEvents

Remove created_at field from core models.

Advances #182.
parent b11c07e4
No related branches found
No related tags found
1 merge request!163Mandate use of AlekSIS base model
from datetime import datetime
from typing import Any, Callable, Optional
from django.contrib.contenttypes.models import ContentType
......@@ -8,9 +9,34 @@ from easyaudit.models import CRUDEvent
from jsonstore.fields import JSONField, JSONFieldMixin
class ExtensibleModel(models.Model):
""" Allow injection of fields and code from AlekSIS apps to extend
model functionality.
class CRUDMixin(models.Model):
class Meta:
abstract = True
@property
def crud_events(self) -> QuerySet:
"""Get all CRUD events connected to this object from easyaudit."""
content_type = ContentType.objects.get_for_model(self)
return CRUDEvent.objects.filter(
object_id=self.pk, content_type=content_type
).select_related("user")
class ExtensibleModel(CRUDMixin):
""" Base model for all objects in AlekSIS apps
This base model ensures all objects in AlekSIS apps fulfill the
following properties:
* crud_events property to retrieve easyaudit's CRUD event log
* created_at and updated_at properties based n CRUD events
* Allow injection of fields and code from AlekSIS apps to extend
model functionality.
Injection of fields and code
============================
After all apps have been loaded, the code in the `model_extensions` module
in every app is executed. All code that shall be injected into a model goes there.
......@@ -43,8 +69,24 @@ class ExtensibleModel(models.Model):
- Dominik George <dominik.george@teckids.org>
"""
@property
def created_at(self) -> Optional[datetime]:
""" Determine creation timestamp from CRUD log """
event = self.crud_events.filter(event_type=CRUDEvent.CREATE).latest("datetime")
if event:
return event.datetime
@property
def updated_at(self) -> Optional[datetime]:
""" Determine last timestamp from CRUD log """
event = self.crud_events.latest("datetime")
if event:
return event.datetime
extended_data = JSONField(default=dict, editable=False)
@classmethod
def _safe_add(cls, obj: Any, name: Optional[str]) -> None:
# Decide the name for the attribute
......@@ -100,18 +142,3 @@ class ExtensibleModel(models.Model):
class Meta:
abstract = True
class CRUDMixin(models.Model):
class Meta:
abstract = True
@property
def crud_events(self) -> QuerySet:
"""Get all CRUD events connected to this object from easyaudit."""
content_type = ContentType.objects.get_for_model(self)
return CRUDEvent.objects.filter(
object_id=self.pk, content_type=content_type
).select_related("user")
......@@ -236,7 +236,7 @@ class Group(ExtensibleModel):
return "%s (%s)" % (self.name, self.short_name)
class Activity(models.Model):
class Activity(ExtensibleModel):
user = models.ForeignKey("Person", on_delete=models.CASCADE, related_name="activities")
title = models.CharField(max_length=150, verbose_name=_("Title"))
......@@ -244,8 +244,6 @@ class Activity(models.Model):
app = models.CharField(max_length=100, verbose_name=_("Application"))
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created at"))
def __str__(self):
return self.title
......@@ -254,7 +252,7 @@ class Activity(models.Model):
verbose_name_plural = _("Activities")
class Notification(models.Model):
class Notification(ExtensibleModel):
sender = models.CharField(max_length=100, verbose_name=_("Sender"))
recipient = models.ForeignKey("Person", on_delete=models.CASCADE, related_name="notifications")
......@@ -265,8 +263,6 @@ class Notification(models.Model):
read = models.BooleanField(default=False, verbose_name=_("Read"))
sent = models.BooleanField(default=False, verbose_name=_("Sent"))
created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created at"))
def __str__(self):
return self.title
......@@ -280,7 +276,7 @@ class Notification(models.Model):
verbose_name_plural = _("Notifications")
class Announcement(models.Model):
class Announcement(ExtensibleModel):
title = models.CharField(max_length=150, verbose_name=_("Title"))
description = models.TextField(max_length=500, verbose_name=_("Description"), blank=True)
link = models.URLField(blank=True, verbose_name=_("Link"))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment