From e7088d18d4f4efd99eb3bc26bf4a20269dc2055d Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 10 Dec 2024 20:11:44 -0500 Subject: [PATCH] add database converters for ArrayField --- django_mongodb/features.py | 4 ---- django_mongodb/operations.py | 20 ++++++++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/django_mongodb/features.py b/django_mongodb/features.py index f5512f12..6e404ea9 100644 --- a/django_mongodb/features.py +++ b/django_mongodb/features.py @@ -92,8 +92,6 @@ class DatabaseFeatures(BaseDatabaseFeatures): "model_fields_.test_arrayfield.TestQuerying.test_exact_with_expression", # int() argument must be a string, a bytes-like object or a real number, not 'list' "model_fields_.test_arrayfield.TestQuerying.test_index_annotation", - # the JSON object must be str, bytes or bytearray, not dict - "model_fields_.test_arrayfield.TestSaveLoad.test_other_array_types", # Wrong results "model_fields_.test_arrayfield.TestQuerying.test_exact", "model_fields_.test_arrayfield.TestQuerying.test_gt", @@ -111,8 +109,6 @@ class DatabaseFeatures(BaseDatabaseFeatures): "model_fields_.test_arrayfield.TestQuerying.test_slice", "model_fields_.test_arrayfield.TestQuerying.test_slice_annotation", "model_fields_.test_arrayfield.TestQuerying.test_usage_in_subquery", - # database converters not applied - "model_fields_.test_arrayfield.TestSaveLoad.test_dates", } # $bitAnd, #bitOr, and $bitXor are new in MongoDB 6.3. _django_test_expected_failures_bitwise = { diff --git a/django_mongodb/operations.py b/django_mongodb/operations.py index a6363bed..ea19a800 100644 --- a/django_mongodb/operations.py +++ b/django_mongodb/operations.py @@ -9,7 +9,7 @@ from django.db import DataError from django.db.backends.base.operations import BaseDatabaseOperations from django.db.models import TextField -from django.db.models.expressions import Combinable +from django.db.models.expressions import Combinable, Expression from django.db.models.functions import Cast from django.utils import timezone from django.utils.regex_helper import _lazy_re_compile @@ -77,10 +77,26 @@ def adapt_timefield_value(self, value): raise ValueError("MongoDB backend does not support timezone-aware times.") return datetime.datetime.combine(datetime.datetime.min.date(), value) + def _get_arrayfield_converter(self, converter, *args, **kwargs): + # Return a database converter that can be applied to a list of values. + def convert_value(value, expression, connection): + return [converter(x, expression, connection) for x in value] + + return convert_value + def get_db_converters(self, expression): converters = super().get_db_converters(expression) internal_type = expression.output_field.get_internal_type() - if internal_type == "DateField": + if internal_type == "ArrayField": + converters.extend( + [ + self._get_arrayfield_converter(converter) + for converter in self.get_db_converters( + Expression(output_field=expression.output_field.base_field) + ) + ] + ) + elif internal_type == "DateField": converters.append(self.convert_datefield_value) elif internal_type == "DateTimeField": if settings.USE_TZ: