Skip to content

Commit 46fe9d5

Browse files
committed
edits
1 parent 91e9b3a commit 46fe9d5

File tree

4 files changed

+76
-82
lines changed

4 files changed

+76
-82
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ Migrations for 'admin':
115115
- `distinct()`
116116
- `extra()`
117117

118+
- `Subquery`, `Exists`, and using a `QuerySet` in `QuerySet.annotate()` aren't
119+
supported.
120+
118121
- `DateTimeField` doesn't support microsecond precision, and correspondingly,
119122
`DurationField` stores milliseconds rather than microseconds.
120123

django_mongodb/compiler.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,11 @@ def _make_result(self, entity, columns, converters, tuple_expected=False):
8383
result = []
8484
for name, col in columns:
8585
field = col.field
86+
column_alias = getattr(col, "alias", None)
8687
obj = (
87-
entity.get(col.alias, {})
88-
if hasattr(col, "alias") and col.alias != self.collection_name
88+
entity.get(column_alias, {})
89+
# Does this column refer to an object for select_related()?
90+
if column_alias is not None and column_alias != self.collection_name
8991
else entity
9092
)
9193
value = obj.get(name, NOT_PROVIDED)
@@ -149,7 +151,7 @@ def build_query(self, columns=None):
149151
self.check_query()
150152
self.setup_query()
151153
query = self.query_class(self, columns)
152-
query.lookups_pipeline = self.get_lookup_clauses()
154+
query.lookup_pipeline = self.get_lookup_pipeline()
153155
try:
154156
query.mongo_query = {"$expr": self.query.where.as_mql(self, self.connection)}
155157
except FullResultSet:
@@ -166,7 +168,7 @@ def get_columns(self):
166168
columns = (
167169
self.get_default_columns(select_mask) if self.query.default_cols else self.query.select
168170
)
169-
171+
# Populate QuerySet.select_related() data.
170172
related_columns = []
171173
if self.query.select_related:
172174
self.get_related_selections(related_columns, select_mask)
@@ -235,16 +237,12 @@ def collection_name(self):
235237
def get_collection(self):
236238
return self.connection.get_collection(self.collection_name)
237239

238-
def get_lookup_clauses(self):
240+
def get_lookup_pipeline(self):
239241
result = []
240242
for alias in tuple(self.query.alias_map):
241243
if not self.query.alias_refcount[alias] or self.collection_name == alias:
242244
continue
243-
244-
from_clause = self.query.alias_map[alias]
245-
clause_mql = from_clause.as_mql(self, self.connection)
246-
result += clause_mql
247-
245+
result += self.query.alias_map[alias].as_mql(self, self.connection)
248246
return result
249247

250248

django_mongodb/features.py

Lines changed: 53 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,31 @@ class DatabaseFeatures(BaseDatabaseFeatures):
3434
"db_functions.text.test_strindex.StrIndexTests.test_order_by",
3535
"expressions_case.tests.CaseExpressionTests.test_order_by_conditional_explicit",
3636
"lookup.tests.LookupQueryingTests.test_lookup_in_order_by",
37+
"ordering.tests.OrderingTests.test_default_ordering",
3738
"ordering.tests.OrderingTests.test_default_ordering_by_f_expression",
3839
"ordering.tests.OrderingTests.test_default_ordering_does_not_affect_group_by",
40+
"ordering.tests.OrderingTests.test_order_by_expr_query_reuse",
3941
"ordering.tests.OrderingTests.test_order_by_expression_ref",
4042
"ordering.tests.OrderingTests.test_order_by_f_expression",
4143
"ordering.tests.OrderingTests.test_order_by_f_expression_duplicates",
44+
"ordering.tests.OrderingTests.test_order_by_fk_attname",
45+
"ordering.tests.OrderingTests.test_order_by_nulls_first",
46+
"ordering.tests.OrderingTests.test_order_by_nulls_last",
4247
"ordering.tests.OrderingTests.test_ordering_select_related_collision",
48+
"ordering.tests.OrderingTests.test_order_by_self_referential_fk",
49+
"ordering.tests.OrderingTests.test_orders_nulls_first_on_filtered_subquery",
50+
"ordering.tests.OrderingTests.test_related_ordering_duplicate_table_reference",
4351
"ordering.tests.OrderingTests.test_reverse_ordering_pure",
52+
"ordering.tests.OrderingTests.test_reverse_meta_ordering_pure",
53+
"ordering.tests.OrderingTests.test_reversed_ordering",
54+
"update.tests.AdvancedTests.test_update_ordered_by_inline_m2m_annotation",
55+
"update.tests.AdvancedTests.test_update_ordered_by_m2m_annotation",
56+
"update.tests.AdvancedTests.test_update_ordered_by_m2m_annotation_desc",
4457
# 'ManyToOneRel' object has no attribute 'column'
4558
"m2m_through.tests.M2mThroughTests.test_order_by_relational_field_through_model",
59+
# pymongo: ValueError: update cannot be empty
60+
"update.tests.SimpleTest.test_empty_update_with_inheritance",
61+
"update.tests.SimpleTest.test_nonempty_update_with_inheritance",
4662
# Pattern lookups that use regexMatch don't work on JSONField:
4763
# Unsupported conversion from array to string in $convert
4864
"model_fields.test_jsonfield.TestQuerying.test_icontains",
@@ -62,6 +78,19 @@ class DatabaseFeatures(BaseDatabaseFeatures):
6278
"model_fields.test_jsonfield.TestQuerying.test_order_grouping_custom_decoder",
6379
"model_fields.test_jsonfield.TestQuerying.test_ordering_by_transform",
6480
"model_fields.test_jsonfield.TestQuerying.test_ordering_grouping_by_key_transform",
81+
# DecimalField lookup with F expressoin crashes:
82+
# decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
83+
"lookup.tests.LookupTests.test_lookup_rhs",
84+
# Wrong results in queries with multiple tables.
85+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_aggregate_with_m2o",
86+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_reverse_m2m",
87+
"annotations.tests.NonAggregateAnnotationTestCase.test_chaining_annotation_filter_with_m2m",
88+
"lookup.tests.LookupTests.test_lookup_collision",
89+
"expressions_case.tests.CaseExpressionTests.test_join_promotion",
90+
"expressions_case.tests.CaseExpressionTests.test_join_promotion_multiple_annotations",
91+
"ordering.tests.OrderingTests.test_order_by_grandparent_fk_with_expression_in_default_ordering",
92+
"ordering.tests.OrderingTests.test_order_by_parent_fk_with_expression_in_default_ordering",
93+
"ordering.tests.OrderingTests.test_order_by_ptr_field_with_default_ordering_by_expression",
6594
}
6695
# $bitAnd, #bitOr, and $bitXor are new in MongoDB 6.3.
6796
_django_test_expected_failures_bitwise = {
@@ -148,16 +177,12 @@ def django_test_expected_failures(self):
148177
},
149178
"AutoField not supported.": {
150179
"bulk_create.tests.BulkCreateTests.test_bulk_insert_nullable_fields",
180+
"lookup.tests.LookupTests.test_filter_by_reverse_related_field_transform",
151181
"lookup.tests.LookupTests.test_in_ignore_none_with_unhashable_items",
152182
"model_fields.test_autofield.AutoFieldTests",
153183
"model_fields.test_autofield.BigAutoFieldTests",
154184
"model_fields.test_autofield.SmallAutoFieldTests",
155185
},
156-
"QuerySet.select_related() not supported.": {
157-
"defer_regress.tests.DeferRegressionTest.test_basic",
158-
"defer_regress.tests.DeferRegressionTest.test_common_model_different_mask",
159-
"defer_regress.tests.DeferRegressionTest.test_defer_annotate_select_related",
160-
},
161186
"MongoDB does not enforce UNIQUE constraints.": {
162187
"auth_tests.test_basic.BasicTestCase.test_unicode_username",
163188
"auth_tests.test_migrations.ProxyModelWithSameAppLabelTests.test_migrate_with_existing_target_permission",
@@ -181,21 +206,35 @@ def django_test_expected_failures(self):
181206
},
182207
# https://github.com/mongodb-labs/django-mongodb/issues/12
183208
"QuerySet.aggregate() not supported.": {
209+
"annotations.tests.AliasTests.test_alias_default_alias_expression",
184210
"annotations.tests.AliasTests.test_filter_alias_agg_with_double_f",
185211
"annotations.tests.NonAggregateAnnotationTestCase.test_aggregate_over_annotation",
186212
"annotations.tests.NonAggregateAnnotationTestCase.test_aggregate_over_full_expression_annotation",
187213
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_exists_aggregate_values_chaining",
188214
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_in_f_grouped_by_annotation",
189215
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_subquery_and_aggregate_values_chaining",
190216
"annotations.tests.NonAggregateAnnotationTestCase.test_filter_agg_with_double_f",
217+
"annotations.tests.NonAggregateAnnotationTestCase.test_values_with_pk_annotation",
191218
"expressions_case.tests.CaseExpressionTests.test_aggregate",
192219
"expressions_case.tests.CaseExpressionTests.test_aggregate_with_expression_as_condition",
193220
"expressions_case.tests.CaseExpressionTests.test_aggregate_with_expression_as_value",
194221
"expressions_case.tests.CaseExpressionTests.test_aggregation_empty_cases",
222+
"expressions_case.tests.CaseExpressionTests.test_annotate_with_aggregation_in_condition",
223+
"expressions_case.tests.CaseExpressionTests.test_annotate_with_aggregation_in_predicate",
224+
"expressions_case.tests.CaseExpressionTests.test_annotate_with_aggregation_in_value",
225+
"expressions_case.tests.CaseExpressionTests.test_annotate_with_in_clause",
226+
"expressions_case.tests.CaseExpressionTests.test_filter_with_aggregation_in_condition",
227+
"expressions_case.tests.CaseExpressionTests.test_filter_with_aggregation_in_predicate",
228+
"expressions_case.tests.CaseExpressionTests.test_filter_with_aggregation_in_value",
229+
"expressions_case.tests.CaseExpressionTests.test_m2m_exclude",
230+
"expressions_case.tests.CaseExpressionTests.test_m2m_reuse",
195231
"lookup.tests.LookupQueryingTests.test_aggregate_combined_lookup",
232+
"lookup.test_decimalfield.DecimalFieldLookupTests",
196233
"from_db_value.tests.FromDBValueTest.test_aggregation",
197234
"timezones.tests.LegacyDatabaseTests.test_query_aggregation",
235+
"timezones.tests.LegacyDatabaseTests.test_query_annotation",
198236
"timezones.tests.NewDatabaseTests.test_query_aggregation",
237+
"timezones.tests.NewDatabaseTests.test_query_annotation",
199238
},
200239
"QuerySet.annotate() has some limitations.": {
201240
# annotate() with combined expressions doesn't work:
@@ -209,6 +248,9 @@ def django_test_expected_failures(self):
209248
"annotations.tests.NonAggregateAnnotationTestCase.test_full_expression_annotation_with_aggregation",
210249
"annotations.tests.NonAggregateAnnotationTestCase.test_grouping_by_q_expression_annotation",
211250
"annotations.tests.NonAggregateAnnotationTestCase.test_q_expression_annotation_with_aggregation",
251+
"defer_regress.tests.DeferRegressionTest.test_basic",
252+
"defer_regress.tests.DeferRegressionTest.test_defer_annotate_select_related",
253+
"defer_regress.tests.DeferRegressionTest.test_ticket_16409",
212254
"expressions_case.tests.CaseDocumentationExamples.test_conditional_aggregation_example",
213255
# Func not implemented.
214256
"annotations.tests.NonAggregateAnnotationTestCase.test_custom_functions",
@@ -217,6 +259,8 @@ def django_test_expected_failures(self):
217259
"annotations.tests.NonAggregateAnnotationTestCase.test_mixed_type_annotation_date_interval",
218260
# FieldDoesNotExist with ordering.
219261
"annotations.tests.AliasTests.test_order_by_alias",
262+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_with_m2m",
263+
"annotations.tests.NonAggregateAnnotationTestCase.test_mti_annotations",
220264
"annotations.tests.NonAggregateAnnotationTestCase.test_order_by_aggregate",
221265
"annotations.tests.NonAggregateAnnotationTestCase.test_order_by_annotation",
222266
"expressions.tests.NegatedExpressionTests.test_filter",
@@ -232,6 +276,8 @@ def django_test_expected_failures(self):
232276
"lookup.tests.LookupQueryingTests.test_filter_exists_lhs",
233277
},
234278
"Subquery is not supported on MongoDB.": {
279+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_filter_with_subquery",
280+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_subquery_outerref_transform",
235281
"annotations.tests.NonAggregateAnnotationTestCase.test_empty_queryset_annotation",
236282
"db_functions.datetime.test_extract_trunc.DateFunctionTests.test_extract_outerref",
237283
"db_functions.datetime.test_extract_trunc.DateFunctionTests.test_trunc_subquery_with_parameters",
@@ -241,6 +287,7 @@ def django_test_expected_failures(self):
241287
},
242288
"Using a QuerySet in annotate() is not supported on MongoDB.": {
243289
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_and_alias_filter_in_subquery",
290+
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_and_alias_filter_related_in_subquery",
244291
"annotations.tests.NonAggregateAnnotationTestCase.test_empty_expression_annotation",
245292
"db_functions.comparison.test_coalesce.CoalesceTests.test_empty_queryset",
246293
"expressions_case.tests.CaseExpressionTests.test_in_subquery",
@@ -251,7 +298,6 @@ def django_test_expected_failures(self):
251298
"model_fields.test_jsonfield.TestQuerying.test_usage_in_subquery",
252299
},
253300
"Count doesn't work in QuerySet.annotate()": {
254-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_and_alias_filter_related_in_subquery",
255301
"annotations.tests.AliasTests.test_alias_annotate_with_aggregation",
256302
"annotations.tests.AliasTests.test_order_by_alias_aggregate",
257303
"annotations.tests.NonAggregateAnnotationTestCase.test_annotate_exists",
@@ -289,60 +335,8 @@ def django_test_expected_failures(self):
289335
"ordering.tests.OrderingTests.test_extra_ordering_with_table_name",
290336
"select_related.tests.SelectRelatedTests.test_select_related_with_extra",
291337
},
292-
"Queries with multiple tables are not supported.": {
293-
"annotations.tests.AliasTests.test_alias_default_alias_expression",
294-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_aggregate_with_m2o",
295-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_filter_with_subquery",
296-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_reverse_m2m",
297-
"annotations.tests.NonAggregateAnnotationTestCase.test_mti_annotations",
298-
"annotations.tests.NonAggregateAnnotationTestCase.test_values_with_pk_annotation",
299-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_subquery_outerref_transform",
300-
"annotations.tests.NonAggregateAnnotationTestCase.test_annotation_with_m2m",
301-
"annotations.tests.NonAggregateAnnotationTestCase.test_chaining_annotation_filter_with_m2m",
302-
"db_functions.comparison.test_least.LeastTests.test_related_field",
303-
"db_functions.comparison.test_greatest.GreatestTests.test_related_field",
304-
"defer_regress.tests.DeferRegressionTest.test_ticket_16409",
305-
"expressions_case.tests.CaseExpressionTests.test_annotate_with_aggregation_in_condition",
306-
"expressions_case.tests.CaseExpressionTests.test_annotate_with_aggregation_in_predicate",
307-
"expressions_case.tests.CaseExpressionTests.test_annotate_with_aggregation_in_value",
308-
"expressions_case.tests.CaseExpressionTests.test_annotate_with_in_clause",
309-
"expressions_case.tests.CaseExpressionTests.test_annotate_with_join_in_condition",
310-
"expressions_case.tests.CaseExpressionTests.test_annotate_with_join_in_predicate",
311-
"expressions_case.tests.CaseExpressionTests.test_annotate_with_join_in_value",
312-
"expressions_case.tests.CaseExpressionTests.test_filter_with_aggregation_in_condition",
313-
"expressions_case.tests.CaseExpressionTests.test_filter_with_aggregation_in_predicate",
314-
"expressions_case.tests.CaseExpressionTests.test_filter_with_aggregation_in_value",
315-
"expressions_case.tests.CaseExpressionTests.test_join_promotion",
316-
"expressions_case.tests.CaseExpressionTests.test_join_promotion_multiple_annotations",
317-
"expressions_case.tests.CaseExpressionTests.test_m2m_exclude",
318-
"expressions_case.tests.CaseExpressionTests.test_m2m_reuse",
319-
"lookup.test_decimalfield.DecimalFieldLookupTests",
320-
"lookup.tests.LookupQueryingTests.test_multivalued_join_reuse",
321-
"lookup.tests.LookupTests.test_filter_by_reverse_related_field_transform",
322-
"lookup.tests.LookupTests.test_lookup_collision",
323-
"lookup.tests.LookupTests.test_lookup_rhs",
324-
"model_fields.test_jsonfield.TestQuerying.test_join_key_transform_annotation_expression",
325-
"ordering.tests.OrderingTests.test_default_ordering",
326-
"ordering.tests.OrderingTests.test_order_by_expr_query_reuse",
327-
"ordering.tests.OrderingTests.test_order_by_fk_attname",
328-
"ordering.tests.OrderingTests.test_order_by_grandparent_fk_with_expression_in_default_ordering",
329-
"ordering.tests.OrderingTests.test_order_by_nulls_first",
330-
"ordering.tests.OrderingTests.test_order_by_nulls_last",
331-
"ordering.tests.OrderingTests.test_order_by_parent_fk_with_expression_in_default_ordering",
332-
"ordering.tests.OrderingTests.test_order_by_ptr_field_with_default_ordering_by_expression",
333-
"ordering.tests.OrderingTests.test_order_by_self_referential_fk",
334-
"ordering.tests.OrderingTests.test_orders_nulls_first_on_filtered_subquery",
335-
"ordering.tests.OrderingTests.test_related_ordering_duplicate_table_reference",
336-
"ordering.tests.OrderingTests.test_reverse_meta_ordering_pure",
337-
"ordering.tests.OrderingTests.test_reversed_ordering",
338-
"timezones.tests.LegacyDatabaseTests.test_query_annotation",
339-
"timezones.tests.NewDatabaseTests.test_query_annotation",
338+
"QuerySet.update() crash: Unrecognized expression '$count'": {
340339
"update.tests.AdvancedTests.test_update_annotated_multi_table_queryset",
341-
"update.tests.AdvancedTests.test_update_ordered_by_inline_m2m_annotation",
342-
"update.tests.AdvancedTests.test_update_ordered_by_m2m_annotation",
343-
"update.tests.AdvancedTests.test_update_ordered_by_m2m_annotation_desc",
344-
"update.tests.SimpleTest.test_empty_update_with_inheritance",
345-
"update.tests.SimpleTest.test_nonempty_update_with_inheritance",
346340
},
347341
"Test inspects query for SQL": {
348342
"lookup.tests.LookupTests.test_in_ignore_none",

0 commit comments

Comments
 (0)