Skip to content

Commit f0f46f4

Browse files
committed
test triage and rhs json handle.
1 parent 6b15c0f commit f0f46f4

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

django_mongodb/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
8080
"lte": lambda val: {"$lte": val},
8181
"in": lambda val: {"$in": val},
8282
"range": lambda val: {"$gte": val[0], "$lte": val[1]},
83-
"isnull": lambda val: None if val else {"$ne": None},
83+
"isnull": lambda val: None if val else {"$ne": None, "$exists": True},
8484
"iexact": safe_regex("^%s$", re.IGNORECASE),
8585
"startswith": safe_regex("^%s"),
8686
"istartswith": safe_regex("^%s", re.IGNORECASE),

django_mongodb/expressions.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from django.db.models.expressions import Col, Value
1+
from django.db import NotSupportedError
2+
from django.db.models.expressions import Col, ExpressionWrapper, Value
3+
from django.db.models.functions.comparison import Cast
24

35

46
def col(self, compiler, connection): # noqa: ARG001
@@ -13,7 +15,22 @@ def value_agg(self, compiler, connection): # noqa: ARG001
1315
return {"$literal": self.value}
1416

1517

18+
def expression(self, compiler, connection):
19+
return self.expression.as_mql(compiler, connection)
20+
21+
22+
def expression_agg(self, compiler, connection):
23+
return self.expression.as_mql_agg(compiler, connection)
24+
25+
26+
def cast(self, compiler, connection): # noqa: ARG001
27+
raise NotSupportedError("Cast is not supported on this database backend")
28+
29+
1630
def register_expressions():
1731
Col.as_mql = col
1832
Value.as_mql = value
1933
Value.as_mql_agg = value_agg
34+
ExpressionWrapper.as_mql = expression
35+
ExpressionWrapper.as_mql_agg = expression_agg
36+
Cast.as_mql = cast

django_mongodb/features.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ class DatabaseFeatures(BaseDatabaseFeatures):
6262
"db_functions.math.test_log.LogTests.test_decimal",
6363
# MongoDB gives ROUND(365, -1)=360 instead of 370 like other databases.
6464
"db_functions.math.test_round.RoundTests.test_integer_with_negative_precision",
65+
# Cast is not supported
66+
"model_fields.test_jsonfield.TestQuerying.test_key_transform_expression",
67+
"model_fields.test_jsonfield.TestQuerying.test_key_transform_annotation_expression",
68+
"model_fields.test_jsonfield.TestQuerying.test_nested_key_transform_annotation_expression",
69+
"model_fields.test_jsonfield.TestQuerying.test_nested_key_transform_expression",
70+
# Nand does not exist in Mongo.
71+
"model_fields.test_jsonfield.TestQuerying.test_lookup_exclude",
72+
"model_fields.test_jsonfield.TestQuerying.test_lookup_exclude_nonexistent_key",
6573
}
6674

6775
django_test_skips = {
@@ -172,6 +180,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
172180
# Subquery not supported.
173181
"annotations.tests.NonAggregateAnnotationTestCase.test_empty_queryset_annotation",
174182
"lookup.tests.LookupQueryingTests.test_filter_subquery_lhs",
183+
"model_fields.test_jsonfield.TestQuerying.test_usage_in_subquery",
175184
# ExpressionWrapper not supported.
176185
"annotations.tests.NonAggregateAnnotationTestCase.test_combined_expression_annotation_with_aggregation",
177186
"annotations.tests.NonAggregateAnnotationTestCase.test_combined_f_expression_annotation_with_aggregation",
@@ -206,6 +215,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
206215
"annotations.tests.AliasTests.test_order_by_alias",
207216
"annotations.tests.NonAggregateAnnotationTestCase.test_order_by_aggregate",
208217
"annotations.tests.NonAggregateAnnotationTestCase.test_order_by_annotation",
218+
"model_fields.test_jsonfield.TestQuerying.test_nested_key_transform_on_subquery",
219+
"model_fields.test_jsonfield.TestQuerying.test_ordering_grouping_by_count",
220+
"model_fields.test_jsonfield.TestQuerying.test_obj_subquery_lookup",
209221
},
210222
"Count doesn't work in QuerySet.annotate()": {
211223
"annotations.tests.AliasTests.test_alias_annotate_with_aggregation",
@@ -279,6 +291,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
279291
"update.tests.SimpleTest.test_empty_update_with_inheritance",
280292
"update.tests.SimpleTest.test_foreign_key_update_with_id",
281293
"update.tests.SimpleTest.test_nonempty_update_with_inheritance",
294+
"model_fields.test_jsonfield.TestQuerying.test_ordering_grouping_by_key_transform",
295+
"model_fields.test_jsonfield.TestQuerying.test_ordering_by_transform",
296+
"model_fields.test_jsonfield.TestQuerying.test_order_grouping_custom_decoder",
297+
"model_fields.test_jsonfield.TestQuerying.test_join_key_transform_annotation_expression",
282298
},
283299
"Test inspects query for SQL": {
284300
"lookup.tests.LookupTests.test_in_ignore_none",
@@ -293,6 +309,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
293309
"timezones.tests.NewDatabaseTests.test_cursor_execute_returns_naive_datetime",
294310
"timezones.tests.NewDatabaseTests.test_cursor_explicit_time_zone",
295311
"timezones.tests.NewDatabaseTests.test_raw_sql",
312+
"model_fields.test_jsonfield.TestQuerying.test_key_transform_raw_expression",
313+
"model_fields.test_jsonfield.TestQuerying.test_key_sql_injection_escape",
314+
"model_fields.test_jsonfield.TestQuerying.test_nested_key_transform_raw_expression",
296315
},
297316
"BSON Date type doesn't support microsecond precision.": {
298317
"basic.tests.ModelRefreshTests.test_refresh_unsaved",
@@ -334,6 +353,8 @@ class DatabaseFeatures(BaseDatabaseFeatures):
334353
"Mongodb's Null behaviour is different from sql's": {
335354
"model_fields.test_jsonfield.TestQuerying.test_none_key_and_exact_lookup",
336355
# "model_fields.test_jsonfield.TestQuerying.test_isnull_key",
356+
"model_fields.test_jsonfield.TestSaveLoad.test_json_null_different_from_sql_null",
357+
"model_fields.test_jsonfield.TestQuerying.test_none_key",
337358
},
338359
"Pipeline filtering": {"model_fields.test_jsonfield.TestQuerying.test_icontains"},
339360
}

django_mongodb/fields.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ def from_db_value(self, value, expression, connection):
6363

6464

6565
def json_process_rhs(node, compiler, connection):
66+
rhs = node.rhs
67+
if hasattr(rhs, "as_mql"):
68+
return rhs.as_mql(compiler, connection)
6669
_, value = node.process_rhs(compiler, connection)
6770
lookup_name = node.lookup_name
6871
if lookup_name not in ("in", "range"):

django_mongodb/query_utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def process_lhs(node, compiler, connection, bare_column_ref=False):
1919
return mql
2020

2121

22-
def process_rhs(node, compiler, connection):
22+
def process_rhs(node, compiler, connection, json_column_ref=False):
2323
rhs = node.rhs
2424
if hasattr(rhs, "as_mql"):
2525
return rhs.as_mql(compiler, connection)
@@ -30,11 +30,11 @@ def process_rhs(node, compiler, connection):
3030
value = value[0]
3131
# Remove percent signs added by PatternLookup.process_rhs() for LIKE
3232
# queries.
33-
if lookup_name in ("startswith", "istartswith"):
33+
if lookup_name in ("startswith", "istartswith") and json_column_ref is False:
3434
value = value[:-1]
35-
elif lookup_name in ("endswith", "iendswith"):
35+
elif lookup_name in ("endswith", "iendswith") and json_column_ref is False:
3636
value = value[1:]
37-
elif lookup_name in ("contains", "icontains"):
37+
elif lookup_name in ("contains", "icontains") and json_column_ref is False:
3838
value = value[1:-1]
3939

4040
return connection.ops.prep_lookup_value(value, node.lhs.output_field, node.lookup_name)

0 commit comments

Comments
 (0)