From 9bcc511e2165270da21eb1a50a63d10be2cd24b5 Mon Sep 17 00:00:00 2001 From: Hasan Ramezani Date: Thu, 13 Jul 2023 08:53:47 +0200 Subject: [PATCH] Fix a bug in `serialized_data` with F expressions (#544) --- CHANGELOG.md | 1 + auditlog/models.py | 5 ++++- auditlog_tests/tests.py | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93f8291..410d6fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - fix: Make sure `LogEntry.changes_dict()` returns an empty dict instead of `None` when `json.loads()` returns `None`. ([#472](https://github.com/jazzband/django-auditlog/pull/472)) - fix: Always set remote_addr even if the request has no authenticated user. ([#484](https://github.com/jazzband/django-auditlog/pull/484)) - fix: Fix a bug in getting field's `verbose_name` when model is not accessible. ([508](https://github.com/jazzband/django-auditlog/pull/508)) +- fix: Fix a bug in `serialized_data` with F expressions. ([508](https://github.com/jazzband/django-auditlog/pull/508)) ## 2.2.2 (2023-01-16) diff --git a/auditlog/models.py b/auditlog/models.py index 584cff7..880d71b 100644 --- a/auditlog/models.py +++ b/auditlog/models.py @@ -273,7 +273,10 @@ class LogEntryManager(models.Manager): for field in instance_copy._meta.fields: if not field.is_relation: value = getattr(instance_copy, field.name) - setattr(instance_copy, field.name, field.to_python(value)) + try: + setattr(instance_copy, field.name, field.to_python(value)) + except ValidationError: + continue return instance_copy def _get_applicable_model_fields( diff --git a/auditlog_tests/tests.py b/auditlog_tests/tests.py index 57b920c..f572644 100644 --- a/auditlog_tests/tests.py +++ b/auditlog_tests/tests.py @@ -16,6 +16,7 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser, User from django.contrib.contenttypes.models import ContentType from django.core import management +from django.db import models from django.db.models.signals import pre_save from django.test import RequestFactory, TestCase, override_settings from django.urls import reverse @@ -2244,6 +2245,24 @@ class TestModelSerialization(TestCase): }, ) + def test_f_expressions(self): + serialize_this = SerializeThisModel.objects.create( + label="test label", + nested={"foo": "bar"}, + timestamp=self.test_date, + nullable=1, + ) + serialize_this.nullable = models.F("nullable") + 1 + serialize_this.save() + + log = serialize_this.history.first() + self.assertTrue(isinstance(log, LogEntry)) + self.assertEqual(log.action, 1) + self.assertEqual( + log.serialized_data["fields"]["nullable"], + "F(nullable) + Value(1)", + ) + class TestAccessLog(TestCase): def setUp(self):