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): 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 datetime import date, datetime
from django.db import models from django.db import models
from django.contrib.auth.models import User 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 django.utils.timezone import now, pytz
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
from simple_history import register from simple_history import register
@ -125,3 +127,25 @@ class Training(models.Model):
class MetaInfo(models.Model): class MetaInfo(models.Model):
backup_id = models.TextField() 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'] return request.method in ['OPTIONS', 'HEAD']
def is_admin_director(user): def is_admin_director(user):
if not user:
return False
if user.is_staff: if user.is_staff:
return True 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,
)