diff --git a/auditlog/encoder.py b/auditlog/encoder.py new file mode 100644 index 0000000..43c32b1 --- /dev/null +++ b/auditlog/encoder.py @@ -0,0 +1,16 @@ +from django.core.serializers.json import DjangoJSONEncoder + +from decimal import Decimal + +AUDITLOG_BUGGY_REPR_DATATYPES = (Decimal,) + + +class AuditLogChangesJSONEncoder(DjangoJSONEncoder): + def default(self, obj): + if isinstance(obj, list) and obj: + return [ + str(o) if isinstance(o, AUDITLOG_BUGGY_REPR_DATATYPES) else o + for o in obj + ] + + return super().default(obj) diff --git a/auditlog/models.py b/auditlog/models.py index c28cb1b..4f2069c 100644 --- a/auditlog/models.py +++ b/auditlog/models.py @@ -24,6 +24,7 @@ from django.utils.encoding import smart_str from django.utils.translation import gettext_lazy as _ from auditlog.diff import mask_str +from auditlog.encoder import AuditLogChangesJSONEncoder DEFAULT_OBJECT_REPR = "" @@ -350,7 +351,7 @@ class LogEntry(models.Model): choices=Action.choices, verbose_name=_("action"), db_index=True ) changes_text = models.TextField(blank=True, verbose_name=_("change message")) - changes = models.JSONField(null=True, verbose_name=_("change message")) + changes = models.JSONField(null=True, verbose_name=_("change message"), encoder=AuditLogChangesJSONEncoder) actor = models.ForeignKey( to=settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,