fix commas

This commit is contained in:
pacnpal
2024-11-03 20:21:39 +00:00
parent 1b0fe4588e
commit ed585e6a56
21 changed files with 390 additions and 98 deletions

View File

@@ -0,0 +1,2 @@
# history_tracking/__init__.py
default_app_config = "history_tracking.apps.HistoryTrackingConfig"

View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

20
history_tracking/apps.py Normal file
View File

@@ -0,0 +1,20 @@
# history_tracking/apps.py
from django.apps import AppConfig
class HistoryTrackingConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "history_tracking"
def ready(self):
from .mixins import HistoricalChangeMixin
from .models import Park
models_with_history = [Park]
for model in models_with_history:
# Check if mixin is already applied
if HistoricalChangeMixin not in model.history.model.__bases__:
model.history.model.__bases__ = (
HistoricalChangeMixin,
) + model.history.model.__bases__

View File

View File

@@ -0,0 +1,99 @@
# history_tracking/management/commands/initialize_history.py
from django.core.management.base import BaseCommand
from django.utils import timezone
from django.apps import apps
from django.db.models import Model
from simple_history.models import HistoricalRecords
class Command(BaseCommand):
help = "Initialize history records for existing objects with historical records"
def add_arguments(self, parser):
parser.add_argument(
"--model",
type=str,
help="Specify model in format app_name.ModelName (e.g., history_tracking.Park)",
)
parser.add_argument(
"--all",
action="store_true",
help="Initialize history for all models with historical records",
)
parser.add_argument(
"--force",
action="store_true",
help="Create history even if records already exist",
)
def initialize_model(self, model, force=False):
total = model.objects.count()
initialized = 0
model_name = f"{model._meta.app_label}.{model._meta.model_name}"
self.stdout.write(f"Processing {model_name}: Found {total} records")
for obj in model.objects.all():
try:
if force or not obj.history.exists():
obj.history.create(
history_date=timezone.now(),
history_type="+",
history_change_reason="Initial history record",
**{
field.name: getattr(obj, field.name)
for field in obj._meta.fields
if not isinstance(field, HistoricalRecords)
},
)
initialized += 1
self.stdout.write(f"Created history for {model_name} id={obj.pk}")
except Exception as e:
self.stdout.write(
self.style.ERROR(
f"Error creating history for {model_name} id={obj.pk}: {str(e)}"
)
)
return initialized, total
def handle(self, *args, **options):
if not options["model"] and not options["all"]:
self.stdout.write(
self.style.ERROR("Please specify either --model or --all")
)
return
force = options["force"]
total_initialized = 0
total_records = 0
if options["model"]:
try:
app_label, model_name = options["model"].split(".")
model = apps.get_model(app_label, model_name)
if hasattr(model, "history"):
initialized, total = self.initialize_model(model, force)
total_initialized += initialized
total_records += total
else:
self.stdout.write(
self.style.ERROR(
f'Model {options["model"]} does not have historical records'
)
)
except Exception as e:
self.stdout.write(self.style.ERROR(str(e)))
else:
# Process all models with historical records
for model in apps.get_models():
if hasattr(model, "history"):
initialized, total = self.initialize_model(model, force)
total_initialized += initialized
total_records += total
self.stdout.write(
self.style.SUCCESS(
f"Successfully initialized {total_initialized} of {total_records} total records"
)
)

View File

@@ -0,0 +1,76 @@
# Generated by Django 5.1.2 on 2024-11-03 19:59
import django.db.models.deletion
import history_tracking.mixins
import simple_history.models
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Park",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=200)),
],
),
migrations.CreateModel(
name="HistoricalPark",
fields=[
(
"id",
models.BigIntegerField(
auto_created=True, blank=True, db_index=True, verbose_name="ID"
),
),
("name", models.CharField(max_length=200)),
("history_id", models.AutoField(primary_key=True, serialize=False)),
("history_date", models.DateTimeField(db_index=True)),
("history_change_reason", models.CharField(max_length=100, null=True)),
(
"history_type",
models.CharField(
choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")],
max_length=1,
),
),
(
"history_user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"verbose_name": "historical park",
"verbose_name_plural": "historical parks",
"ordering": ("-history_date", "-history_id"),
"get_latest_by": ("history_date", "history_id"),
},
bases=(
history_tracking.mixins.HistoricalChangeMixin,
simple_history.models.HistoricalChanges,
models.Model,
),
),
]

View File

View File

@@ -0,0 +1,23 @@
# history_tracking/mixins.py
class HistoricalChangeMixin:
@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",
] and not field.startswith("_"):
old_value = getattr(prev_record, field)
new_value = getattr(self, field)
if old_value != new_value:
changes[field] = {"old": old_value, "new": new_value}
return changes

View File

@@ -0,0 +1,17 @@
# history_tracking/models.py
from django.db import models
from simple_history.models import HistoricalRecords
from .mixins import HistoricalChangeMixin
class Park(models.Model):
name = models.CharField(max_length=200)
# ... other fields ...
history = HistoricalRecords()
@property
def _history_model(self):
return self.history.model
# Apply the mixin

View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View File

@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.