Deserialize JobLogEntry timestamp

This commit is contained in:
Jeremy Stretch 2025-07-09 09:30:38 -04:00
parent 92a13a4226
commit e95c3825de
4 changed files with 29 additions and 2 deletions

View File

@ -2,6 +2,8 @@ import django.contrib.postgres.fields
import django.core.serializers.json
from django.db import migrations, models
import utilities.json
class Migration(migrations.Migration):
@ -15,6 +17,7 @@ class Migration(migrations.Migration):
name='log_entries',
field=django.contrib.postgres.fields.ArrayField(
base_field=models.JSONField(
decoder=utilities.json.JobLogDecoder,
encoder=django.core.serializers.json.DjangoJSONEncoder
),
blank=True,

View File

@ -20,6 +20,7 @@ from core.choices import JobStatusChoices
from core.dataclasses import JobLogEntry
from core.models import ObjectType
from core.signals import job_end, job_start
from utilities.json import JobLogDecoder
from utilities.querysets import RestrictedQuerySet
from utilities.rqworker import get_queue_for_model
@ -111,7 +112,7 @@ class Job(models.Model):
log_entries = ArrayField(
base_field=models.JSONField(
encoder=DjangoJSONEncoder,
# TODO: Specify a decoder to handle ISO 8601 timestamps
decoder=JobLogDecoder,
),
blank=True,
default=list,

View File

@ -62,7 +62,8 @@ class JobTable(NetBoxTable):
class JobLogEntryTable(BaseTable):
timestamp = tables.Column(
timestamp = columns.DateTimeColumn(
timespec='milliseconds',
verbose_name=_('Time'),
)
level = tables.Column(

View File

@ -1,10 +1,14 @@
import decimal
import json
from django.core.serializers.json import DjangoJSONEncoder
from utilities.datetime import datetime_from_timestamp
__all__ = (
'ConfigJSONEncoder',
'CustomFieldJSONEncoder',
'JobLogDecoder',
)
@ -29,3 +33,21 @@ class ConfigJSONEncoder(DjangoJSONEncoder):
return type(o).__name__
return super().default(o)
class JobLogDecoder(json.JSONDecoder):
"""
Deserialize JobLogEntry timestamps.
"""
def __init__(self, *args, **kwargs):
kwargs['object_hook'] = self._deserialize_entry
super().__init__(*args, **kwargs)
def _deserialize_entry(self, obj: dict) -> dict:
if obj.get('timestamp'):
# Deserialize a timestamp string to a native datetime object
try:
obj['timestamp'] = datetime_from_timestamp(obj['timestamp'])
except ValueError:
pass
return obj