Create an index of all history changes

This commit is contained in:
Tanner Collin 2020-02-24 23:49:14 +00:00
parent b4b94c277f
commit 73362b69c6
5 changed files with 93 additions and 1 deletions

View File

@ -0,0 +1 @@
default_app_config = 'apiserver.api.apps.ApiConfig'

View File

@ -2,4 +2,7 @@ from django.apps import AppConfig
class ApiConfig(AppConfig):
name = 'api'
name = 'apiserver.api'
def ready(self):
from . import signals

View File

@ -1,6 +1,8 @@
from datetime import date, datetime
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.utils.timezone import now, pytz
from simple_history.models import HistoricalRecords
from simple_history import register
@ -125,3 +127,25 @@ class Training(models.Model):
class MetaInfo(models.Model):
backup_id = models.TextField()
class HistoryIndex(models.Model):
content_type = models.ForeignKey(ContentType, null=True, on_delete=models.SET_NULL)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
owner_id = models.PositiveIntegerField()
owner_name = models.TextField()
history_user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
history_date = models.DateTimeField()
history_type = models.TextField()
revert_url = models.TextField()
is_system = models.BooleanField()
is_admin = models.BooleanField()
class HistoryChange(models.Model):
index = models.ForeignKey(HistoryIndex, related_name='changes', null=True, on_delete=models.SET_NULL)
field = models.TextField()
old = models.TextField()
new = models.TextField()

View File

@ -5,6 +5,9 @@ class AllowMetadata(BasePermission):
return request.method in ['OPTIONS', 'HEAD']
def is_admin_director(user):
if not user:
return False
if user.is_staff:
return True

View File

@ -0,0 +1,61 @@
from django.dispatch import receiver
from simple_history.signals import (
pre_create_historical_record,
post_create_historical_record
)
from . import models
from .permissions import is_admin_director
def get_object_owner(obj):
full_name = lambda member: member.first_name + ' ' + member.last_name
if getattr(obj, 'user', False):
return full_name(obj.user.member), obj.user.member.id
if getattr(obj, 'instructor', False):
return full_name(obj.instructor.member), obj.instructor.member.id
if getattr(obj, 'member_id', False):
try:
member = models.Member.objects.get(id=obj.member_id)
return full_name(member), member.id
except models.Member.DoesNotExist:
pass
return 'Protospace', 0
@receiver(post_create_historical_record, dispatch_uid='create_hist')
def post_create_historical_record_callback(
sender,
instance,
history_instance,
history_change_reason,
history_user,
using,
**kwargs):
changes = history_instance.diff_against(history_instance.prev_record).changes
if changes:
owner = get_object_owner(instance)
index = models.HistoryIndex.objects.create(
content_object=history_instance,
owner_name=owner[0],
owner_id=owner[1],
history_user=history_user,
history_date=history_instance.history_date,
history_type=history_instance.get_history_type_display(),
revert_url=history_instance.revert_url(),
is_system=bool(history_user == None),
is_admin=is_admin_director(history_user),
)
for change in changes:
models.HistoryChange.objects.create(
index=index,
field=change.field,
old=change.old,
new=change.new,
)