Skip to content

Commit 77d6286

Browse files
timgrahamWaVEV
authored andcommitted
add subqueries tests
1 parent fd57ce8 commit 77d6286

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

django_mongodb_backend/compiler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _get_column_from_expression(self, expr, alias):
5353
Create a column named `alias` from the given expression to hold the
5454
aggregate value.
5555
"""
56-
column_target = expr.output_field.__class__()
56+
column_target = expr.output_field.clone()
5757
column_target.db_column = alias
5858
column_target.set_attributes_from_name(alias)
5959
return Col(self.collection_name, column_target)
@@ -81,7 +81,7 @@ def _prepare_expressions_for_pipeline(self, expression, target, annotation_group
8181
alias = (
8282
f"__aggregation{next(annotation_group_idx)}" if sub_expr != expression else target
8383
)
84-
column_target = sub_expr.output_field.__class__()
84+
column_target = sub_expr.output_field.clone()
8585
column_target.db_column = alias
8686
column_target.set_attributes_from_name(alias)
8787
inner_column = Col(self.collection_name, column_target)

tests/model_fields_/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,10 @@ class Author(models.Model):
119119
class Book(models.Model):
120120
name = models.CharField(max_length=100)
121121
author = EmbeddedModelField(Author)
122+
123+
124+
class Library(models.Model):
125+
name = models.CharField(max_length=100)
126+
books = models.ManyToManyField("Book", related_name="libraries")
127+
location = models.CharField(max_length=100, null=True, blank=True)
128+
best_seller = models.CharField(max_length=100, null=True, blank=True)

tests/model_fields_/test_embedded_model.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
from django.core.exceptions import ValidationError
22
from django.db import models
3+
from django.db.models import (
4+
Exists,
5+
OuterRef,
6+
Subquery,
7+
)
38
from django.test import SimpleTestCase, TestCase
49
from django.test.utils import isolate_apps
510

@@ -11,6 +16,7 @@
1116
Book,
1217
Data,
1318
Holder,
19+
Library,
1420
)
1521

1622

@@ -123,3 +129,62 @@ class MyModel(models.Model):
123129
self.assertEqual(
124130
msg, "Embedded models cannot have relational fields (Target.key is a ForeignKey)."
125131
)
132+
133+
134+
class SubqueryExistsTest(TestCase):
135+
def setUp(self):
136+
# Create test data
137+
address1 = Address.objects.create(city="New York", state="NY", zip_code=10001)
138+
address2 = Address.objects.create(city="Boston", state="MA", zip_code=20002)
139+
author1 = Author.objects.create(name="Alice", age=30, address=address1)
140+
author2 = Author.objects.create(name="Bob", age=40, address=address2)
141+
book1 = Book.objects.create(name="Book A", author=author1)
142+
book2 = Book.objects.create(name="Book B", author=author2)
143+
Book.objects.create(name="Book C", author=author2)
144+
Book.objects.create(name="Book D", author=author2)
145+
Book.objects.create(name="Book E", author=author1)
146+
147+
library1 = Library.objects.create(
148+
name="Central Library", location="Downtown", best_seller="Book A"
149+
)
150+
library2 = Library.objects.create(
151+
name="Community Library", location="Suburbs", best_seller="Book A"
152+
)
153+
154+
# Add books to libraries
155+
library1.books.add(book1, book2)
156+
library2.books.add(book2)
157+
158+
def test_exists_subquery(self):
159+
subquery = Book.objects.filter(
160+
author__name=OuterRef("name"), author__address__city="Boston"
161+
)
162+
queryset = Author.objects.filter(Exists(subquery))
163+
164+
self.assertEqual(queryset.count(), 1)
165+
166+
def test_in_subquery(self):
167+
subquery = Author.objects.filter(age__gt=35).values("name")
168+
queryset = Book.objects.filter(author__name__in=Subquery(subquery)).order_by("name")
169+
170+
self.assertEqual(queryset.count(), 3)
171+
self.assertQuerySetEqual(queryset, ["Book B", "Book C", "Book D"], lambda book: book.name)
172+
173+
def test_range_query(self):
174+
queryset = Author.objects.filter(age__range=(25, 45)).order_by("name")
175+
176+
self.assertEqual(queryset.count(), 2)
177+
self.assertQuerySetEqual(queryset, ["Alice", "Bob"], lambda author: author.name)
178+
179+
def test_exists_with_foreign_object(self):
180+
subquery = Library.objects.filter(best_seller=OuterRef("name"))
181+
queryset = Book.objects.filter(Exists(subquery))
182+
183+
self.assertEqual(queryset.count(), 1)
184+
self.assertEqual(queryset.first().name, "Book A")
185+
186+
def test_foreign_field_with_ranges(self):
187+
queryset = Library.objects.filter(books__author__age__range=(25, 35))
188+
189+
self.assertEqual(queryset.count(), 1)
190+
self.assertEqual(queryset.first().name, "Central Library")

0 commit comments

Comments
 (0)