|
2 | 2 |
|
3 | 3 | from django.core.exceptions import FieldDoesNotExist, ValidationError
|
4 | 4 | from django.db import models
|
5 |
| -from django.db.models import ExpressionWrapper, F, Max, Sum |
| 5 | +from django.db.models import ( |
| 6 | + Exists, |
| 7 | + ExpressionWrapper, |
| 8 | + F, |
| 9 | + Max, |
| 10 | + OuterRef, |
| 11 | + Subquery, |
| 12 | + Sum, |
| 13 | +) |
6 | 14 | from django.test import SimpleTestCase, TestCase
|
7 | 15 | from django.test.utils import isolate_apps
|
8 | 16 |
|
|
15 | 23 | Book,
|
16 | 24 | Data,
|
17 | 25 | Holder,
|
| 26 | + Library, |
18 | 27 | )
|
19 | 28 | from .utils import truncate_ms
|
20 | 29 |
|
@@ -214,3 +223,61 @@ class MyModel(models.Model):
|
214 | 223 | msg,
|
215 | 224 | "Embedded models must be a subclass of django_mongodb_backend.models.EmbeddedModel.",
|
216 | 225 | )
|
| 226 | + |
| 227 | +class SubqueryExistsTest(TestCase): |
| 228 | + def setUp(self): |
| 229 | + # Create test data |
| 230 | + address1 = Address.objects.create(city="New York", state="NY", zip_code=10001) |
| 231 | + address2 = Address.objects.create(city="Boston", state="MA", zip_code=20002) |
| 232 | + author1 = Author.objects.create(name="Alice", age=30, address=address1) |
| 233 | + author2 = Author.objects.create(name="Bob", age=40, address=address2) |
| 234 | + book1 = Book.objects.create(name="Book A", author=author1) |
| 235 | + book2 = Book.objects.create(name="Book B", author=author2) |
| 236 | + Book.objects.create(name="Book C", author=author2) |
| 237 | + Book.objects.create(name="Book D", author=author2) |
| 238 | + Book.objects.create(name="Book E", author=author1) |
| 239 | + |
| 240 | + library1 = Library.objects.create( |
| 241 | + name="Central Library", location="Downtown", best_seller="Book A" |
| 242 | + ) |
| 243 | + library2 = Library.objects.create( |
| 244 | + name="Community Library", location="Suburbs", best_seller="Book A" |
| 245 | + ) |
| 246 | + |
| 247 | + # Add books to libraries |
| 248 | + library1.books.add(book1, book2) |
| 249 | + library2.books.add(book2) |
| 250 | + |
| 251 | + def test_exists_subquery(self): |
| 252 | + subquery = Book.objects.filter( |
| 253 | + author__name=OuterRef("name"), author__address__city="Boston" |
| 254 | + ) |
| 255 | + queryset = Author.objects.filter(Exists(subquery)) |
| 256 | + |
| 257 | + self.assertEqual(queryset.count(), 1) |
| 258 | + |
| 259 | + def test_in_subquery(self): |
| 260 | + subquery = Author.objects.filter(age__gt=35).values("name") |
| 261 | + queryset = Book.objects.filter(author__name__in=Subquery(subquery)).order_by("name") |
| 262 | + |
| 263 | + self.assertEqual(queryset.count(), 3) |
| 264 | + self.assertQuerySetEqual(queryset, ["Book B", "Book C", "Book D"], lambda book: book.name) |
| 265 | + |
| 266 | + def test_range_query(self): |
| 267 | + queryset = Author.objects.filter(age__range=(25, 45)).order_by("name") |
| 268 | + |
| 269 | + self.assertEqual(queryset.count(), 2) |
| 270 | + self.assertQuerySetEqual(queryset, ["Alice", "Bob"], lambda author: author.name) |
| 271 | + |
| 272 | + def test_exists_with_foreign_object(self): |
| 273 | + subquery = Library.objects.filter(best_seller=OuterRef("name")) |
| 274 | + queryset = Book.objects.filter(Exists(subquery)) |
| 275 | + |
| 276 | + self.assertEqual(queryset.count(), 1) |
| 277 | + self.assertEqual(queryset.first().name, "Book A") |
| 278 | + |
| 279 | + def test_foreign_field_with_ranges(self): |
| 280 | + queryset = Library.objects.filter(books__author__age__range=(25, 35)) |
| 281 | + |
| 282 | + self.assertEqual(queryset.count(), 1) |
| 283 | + self.assertEqual(queryset.first().name, "Central Library") |
0 commit comments