diff --git a/easyaudit/tests/test_app/tests.py b/easyaudit/tests/test_app/tests.py index 2bc27b10..cd7d96e8 100644 --- a/easyaudit/tests/test_app/tests.py +++ b/easyaudit/tests/test_app/tests.py @@ -4,6 +4,9 @@ from unittest import skip, skipIf import django +from django.db.models import BinaryField + +from easyaudit.utils import get_field_value asgi_views_supported = django.VERSION >= (3, 1) if asgi_views_supported: @@ -246,3 +249,25 @@ def test_request_event_admin_no_users(self): response = self.client.get(reverse('admin:easyaudit_requestevent_changelist')) self.assertEqual(200, response.status_code) filters = self._list_filters(response.content) + + +@override_settings(TEST=True) +class TestBinaryData(TestCase): + def test_binary_data(self): + class FakeObject: + pass + obj = FakeObject() + obj.binary_data = b'\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00' + binary_field = BinaryField() + binary_field.name = 'binary_data' + + # Small + actual = get_field_value(obj, binary_field) + expected = r"b'\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00'" + assert actual == expected + + # Large + obj.binary_data = b'\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00' * 100 + actual = get_field_value(obj, binary_field) + assert actual.startswith(expected[:-1]) + assert actual.endswith('[truncated 2000 bytes]') diff --git a/easyaudit/utils.py b/easyaudit/utils.py index dc0b8479..2c699902 100644 --- a/easyaudit/utils.py +++ b/easyaudit/utils.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from uuid import UUID - from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from django.db.models import NOT_PROVIDED, DateTimeField @@ -19,15 +17,21 @@ def get_field_value(obj, field): :return: The value of the field as a string. :rtype: str """ + raw_value = getattr(obj, field.name, None) if isinstance(field, DateTimeField): # DateTimeFields are timezone-aware, so we need to convert the field # to its naive form before we can accurately compare them for changes. try: - value = field.to_python(getattr(obj, field.name, None)) + value = field.to_python(raw_value) if value is not None and settings.USE_TZ and not timezone.is_naive(value): value = timezone.make_naive(value, timezone=timezone.utc) except ObjectDoesNotExist: value = field.default if field.default is not NOT_PROVIDED else None + elif isinstance(raw_value, bytes): + if len(raw_value) > 100: + return repr(raw_value[:100]) + '[truncated {} bytes]'.format(len(raw_value) - 100) + else: + return repr(raw_value) else: try: value = smart_str(getattr(obj, field.name, None))