mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 11:31:07 -05:00
- Add HTMX-powered filtering with instant updates - Add smooth transitions and loading states - Improve visual hierarchy and styling - Add review notes functionality - Add confirmation dialogs for actions - Make navigation sticky - Add hover effects and visual feedback - Improve dark mode support
75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
# history_tracking/mixins.py
|
|
from django.db import models
|
|
from django.conf import settings
|
|
|
|
class HistoricalChangeMixin(models.Model):
|
|
"""Mixin for historical models to track changes"""
|
|
id = models.BigIntegerField(db_index=True, auto_created=True, blank=True)
|
|
history_date = models.DateTimeField()
|
|
history_id = models.AutoField(primary_key=True)
|
|
history_type = models.CharField(max_length=1)
|
|
history_user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
null=True,
|
|
on_delete=models.SET_NULL,
|
|
related_name='+'
|
|
)
|
|
history_change_reason = models.CharField(max_length=100, null=True)
|
|
|
|
class Meta:
|
|
abstract = True
|
|
ordering = ['-history_date', '-history_id']
|
|
|
|
@property
|
|
def prev_record(self):
|
|
"""Get the previous record for this instance"""
|
|
try:
|
|
return self.__class__.objects.filter(
|
|
history_date__lt=self.history_date,
|
|
id=self.id
|
|
).order_by('-history_date').first()
|
|
except (AttributeError, TypeError):
|
|
return None
|
|
|
|
@property
|
|
def diff_against_previous(self):
|
|
prev_record = self.prev_record
|
|
if not prev_record:
|
|
return {}
|
|
|
|
changes = {}
|
|
for field in self.__dict__:
|
|
if field not in [
|
|
"history_date",
|
|
"history_id",
|
|
"history_type",
|
|
"history_user_id",
|
|
"history_change_reason",
|
|
"history_type",
|
|
"id",
|
|
"_state",
|
|
"_history_user_cache"
|
|
] and not field.startswith("_"):
|
|
try:
|
|
old_value = getattr(prev_record, field)
|
|
new_value = getattr(self, field)
|
|
if old_value != new_value:
|
|
changes[field] = {"old": str(old_value), "new": str(new_value)}
|
|
except AttributeError:
|
|
continue
|
|
return changes
|
|
|
|
@property
|
|
def history_user_display(self):
|
|
"""Get a display name for the history user"""
|
|
if hasattr(self, 'history_user') and self.history_user:
|
|
return str(self.history_user)
|
|
return None
|
|
|
|
def get_instance(self):
|
|
"""Get the model instance this history record represents"""
|
|
try:
|
|
return self.__class__.objects.get(id=self.id)
|
|
except self.__class__.DoesNotExist:
|
|
return None
|