|  | 
| 11 | 11 | 
 | 
| 12 | 12 | from django_mongodb_backend.fields import ArrayField, EmbeddedModelArrayField | 
| 13 | 13 | from django_mongodb_backend.models import EmbeddedModel | 
|  | 14 | +from django_mongodb_backend.test import MongoTestCaseMixin | 
| 14 | 15 | 
 | 
| 15 | 16 | from .models import Artifact, Audit, Exhibit, Movie, Restoration, Review, Section, Tour | 
| 16 | 17 | 
 | 
| @@ -85,7 +86,7 @@ def test_embedded_model_field_respects_db_column(self): | 
| 85 | 86 |  self.assertEqual(query[0]["reviews"][0]["title_"], "Awesome") | 
| 86 | 87 | 
 | 
| 87 | 88 | 
 | 
| 88 |  | -class QueryingTests(TestCase): | 
|  | 89 | +class QueryingTests(MongoTestCaseMixin, TestCase): | 
| 89 | 90 |  @classmethod | 
| 90 | 91 |  def setUpTestData(cls): | 
| 91 | 92 |  cls.egypt = Exhibit.objects.create( | 
| @@ -178,15 +179,55 @@ def setUpTestData(cls): | 
| 178 | 179 |  cls.audit_2 = Audit.objects.create(section_number=2, reviewed=True) | 
| 179 | 180 |  cls.audit_3 = Audit.objects.create(section_number=5, reviewed=False) | 
| 180 | 181 | 
 | 
| 181 |  | - def test_exact(self): | 
| 182 |  | - self.assertCountEqual( | 
| 183 |  | - Exhibit.objects.filter(sections__number=1), [self.egypt, self.wonders] | 
|  | 182 | + def test_exact_expr(self): | 
|  | 183 | + with self.assertNumQueries(1) as ctx: | 
|  | 184 | + self.assertCountEqual( | 
|  | 185 | + Exhibit.objects.filter(sections__number=Value(2) - 1), [self.egypt, self.wonders] | 
|  | 186 | + ) | 
|  | 187 | + query = ctx.captured_queries[0]["sql"] | 
|  | 188 | + self.assertAggregateQuery( | 
|  | 189 | + query, | 
|  | 190 | + "model_fields__exhibit", | 
|  | 191 | + [ | 
|  | 192 | + { | 
|  | 193 | + "$match": { | 
|  | 194 | + "$expr": { | 
|  | 195 | + "$anyElementTrue": { | 
|  | 196 | + "$ifNull": [ | 
|  | 197 | + { | 
|  | 198 | + "$map": { | 
|  | 199 | + "input": "$sections", | 
|  | 200 | + "as": "item", | 
|  | 201 | + "in": { | 
|  | 202 | + "$eq": [ | 
|  | 203 | + "$$item.number", | 
|  | 204 | + { | 
|  | 205 | + "$subtract": [ | 
|  | 206 | + {"$literal": 2}, | 
|  | 207 | + {"$literal": 1}, | 
|  | 208 | + ] | 
|  | 209 | + }, | 
|  | 210 | + ] | 
|  | 211 | + }, | 
|  | 212 | + } | 
|  | 213 | + }, | 
|  | 214 | + [], | 
|  | 215 | + ] | 
|  | 216 | + } | 
|  | 217 | + } | 
|  | 218 | + } | 
|  | 219 | + } | 
|  | 220 | + ], | 
| 184 | 221 |  ) | 
| 185 | 222 | 
 | 
| 186 |  | - def test_array_index(self): | 
| 187 |  | - self.assertCountEqual( | 
| 188 |  | - Exhibit.objects.filter(sections__0__number=1), | 
| 189 |  | - [self.egypt, self.wonders], | 
|  | 223 | + def test_exact_path(self): | 
|  | 224 | + with self.assertNumQueries(1) as ctx: | 
|  | 225 | + self.assertCountEqual( | 
|  | 226 | + Exhibit.objects.filter(sections__number=1), [self.egypt, self.wonders] | 
|  | 227 | + ) | 
|  | 228 | + query = ctx.captured_queries[0]["sql"] | 
|  | 229 | + self.assertAggregateQuery( | 
|  | 230 | + query, "model_fields__exhibit", [{"$match": {"sections.number": 1}}] | 
| 190 | 231 |  ) | 
| 191 | 232 | 
 | 
| 192 | 233 |  def test_array_index_expr(self): | 
| @@ -316,8 +357,20 @@ def test_filter_unsupported_lookups_in_json(self): | 
| 316 | 357 |  kwargs = {f"main_section__artifacts__metadata__origin__{lookup}": ["Pergamon", "Egypt"]} | 
| 317 | 358 |  with CaptureQueriesContext(connection) as captured_queries: | 
| 318 | 359 |  self.assertCountEqual(Exhibit.objects.filter(**kwargs), []) | 
| 319 |  | - self.assertIn( | 
| 320 |  | - f"'main_section.artifacts.metadata.origin.{lookup}':", captured_queries[0]["sql"] | 
|  | 360 | + query = captured_queries[0]["sql"] | 
|  | 361 | + self.assertAggregateQuery( | 
|  | 362 | + query, | 
|  | 363 | + "model_fields__exhibit", | 
|  | 364 | + [ | 
|  | 365 | + { | 
|  | 366 | + "$match": { | 
|  | 367 | + f"main_section.artifacts.metadata.origin.{lookup}": [ | 
|  | 368 | + "Pergamon", | 
|  | 369 | + "Egypt", | 
|  | 370 | + ] | 
|  | 371 | + } | 
|  | 372 | + } | 
|  | 373 | + ], | 
| 321 | 374 |  ) | 
| 322 | 375 | 
 | 
| 323 | 376 |  def test_len(self): | 
| @@ -421,10 +474,12 @@ def test_nested_lookup(self): | 
| 421 | 474 |  with self.assertRaisesMessage(ValueError, msg): | 
| 422 | 475 |  Exhibit.objects.filter(sections__artifacts__name="") | 
| 423 | 476 | 
 | 
| 424 |  | - def test_foreign_field_exact(self): | 
|  | 477 | + def test_foreign_field_exact_path(self): | 
| 425 | 478 |  """Querying from a foreign key to an EmbeddedModelArrayField.""" | 
| 426 |  | - qs = Tour.objects.filter(exhibit__sections__number=1) | 
| 427 |  | - self.assertCountEqual(qs, [self.egypt_tour, self.wonders_tour]) | 
|  | 479 | + with self.assertNumQueries(1) as ctx: | 
|  | 480 | + qs = Tour.objects.filter(exhibit__sections__number=1) | 
|  | 481 | + self.assertCountEqual(qs, [self.egypt_tour, self.wonders_tour]) | 
|  | 482 | + self.assertNotIn("anyElementTrue", ctx.captured_queries[0]["sql"]) | 
| 428 | 483 | 
 | 
| 429 | 484 |  def test_foreign_field_exact_expr(self): | 
| 430 | 485 |  """Querying from a foreign key to an EmbeddedModelArrayField.""" | 
|  | 
0 commit comments