Skip to content

Commit 98cc6d6

Browse files
committed
INTPYTHON-602 Fix loading of embedded model fields that use database converters
1 parent 9ce9ef3 commit 98cc6d6

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

django_mongodb_backend/fields/embedded_model.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.core import checks
44
from django.core.exceptions import FieldDoesNotExist
55
from django.db import models
6+
from django.db.models.expressions import Col
67
from django.db.models.fields.related import lazy_related_operation
78
from django.db.models.lookups import Transform
89

@@ -76,6 +77,15 @@ def _resolve_lookup(_, resolved_model):
7677
model = property(lambda self: self._model, _set_model)
7778

7879
def from_db_value(self, value, expression, connection):
80+
if value is None:
81+
return None
82+
if not isinstance(value, dict):
83+
return value
84+
for field in self.embedded_model._meta.fields:
85+
expression = Col("", field)
86+
converters = connection.ops.get_db_converters(expression)
87+
for converter in converters:
88+
value[field.attname] = converter(value[field.attname], expression, connection)
7989
return self.to_python(value)
8090

8191
def to_python(self, value):

tests/model_fields_/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class Data(EmbeddedModel):
104104
auto_now = models.DateTimeField(auto_now=True)
105105
auto_now_add = models.DateTimeField(auto_now_add=True)
106106
json_value = models.JSONField()
107+
decimal = models.DecimalField(max_digits=9, decimal_places="2")
107108

108109

109110
class Address(EmbeddedModel):

tests/model_fields_/test_embedded_model.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import operator
22
from datetime import timedelta
3+
from unittest import expectedFailure
34

45
from django.core.exceptions import FieldDoesNotExist, ValidationError
56
from django.db import models
@@ -93,7 +94,7 @@ def test_pre_save(self):
9394
class QueryingTests(TestCase):
9495
@classmethod
9596
def setUpTestData(cls):
96-
cls.objs = [Holder.objects.create(data=Data(integer=x)) for x in range(6)]
97+
cls.objs = [Holder.objects.create(data=Data(integer=x, decimal=f"{x}.5")) for x in range(6)]
9798

9899
def test_exact(self):
99100
self.assertCountEqual(Holder.objects.filter(data__integer=3), [self.objs[3]])
@@ -113,6 +114,12 @@ def test_gte(self):
113114
def test_range(self):
114115
self.assertCountEqual(Holder.objects.filter(data__integer__range=(2, 4)), self.objs[2:5])
115116

117+
@expectedFailure
118+
def test_exact_decimal(self):
119+
# EmbeddedModelField lookups need to call
120+
# DatabaseOperations.adapt__<foo>field_value().
121+
self.assertCountEqual(Holder.objects.filter(data__decimal="3.5"), [self.objs[3]])
122+
116123
def test_order_by_embedded_field(self):
117124
qs = Holder.objects.filter(data__integer__gt=3).order_by("-data__integer")
118125
self.assertSequenceEqual(qs, list(reversed(self.objs[4:])))

0 commit comments

Comments
 (0)