From 16f005ed413c46293ccbcb35b935b7d5f620ad8b Mon Sep 17 00:00:00 2001 From: Emanuel Lupi Date: Fri, 6 Dec 2024 21:12:40 -0500 Subject: [PATCH 1/2] add subquery tests for EmbeddedModelField --- tests/model_fields_/models.py | 9 ++++ tests/model_fields_/test_embedded_model.py | 48 +++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/tests/model_fields_/models.py b/tests/model_fields_/models.py index c0cd6402..0420249c 100644 --- a/tests/model_fields_/models.py +++ b/tests/model_fields_/models.py @@ -120,3 +120,12 @@ class Author(EmbeddedModel): class Book(models.Model): name = models.CharField(max_length=100) author = EmbeddedModelField(Author) + + +class Library(models.Model): + name = models.CharField(max_length=100) + books = models.ManyToManyField("Book", related_name="libraries") + best_seller = models.CharField(max_length=100, null=True, blank=True) + + def __str__(self): + return self.name diff --git a/tests/model_fields_/test_embedded_model.py b/tests/model_fields_/test_embedded_model.py index 2f5fb1d2..57616597 100644 --- a/tests/model_fields_/test_embedded_model.py +++ b/tests/model_fields_/test_embedded_model.py @@ -2,7 +2,14 @@ from django.core.exceptions import FieldDoesNotExist, ValidationError from django.db import models -from django.db.models import ExpressionWrapper, F, Max, Sum +from django.db.models import ( + Exists, + ExpressionWrapper, + F, + Max, + OuterRef, + Sum, +) from django.test import SimpleTestCase, TestCase from django.test.utils import isolate_apps @@ -15,6 +22,7 @@ Book, Data, Holder, + Library, ) from .utils import truncate_ms @@ -214,3 +222,41 @@ class MyModel(models.Model): msg, "Embedded models must be a subclass of django_mongodb_backend.models.EmbeddedModel.", ) + + +class SubqueryExistsTests(TestCase): + def setUpTestData(self): + address1 = Address(city="New York", state="NY", zip_code=10001) + address2 = Address(city="Boston", state="MA", zip_code=20002) + author1 = Author(name="Alice", age=30, address=address1) + author2 = Author(name="Bob", age=40, address=address2) + book1 = Book.objects.create(name="Book 1", author=author1) + book2 = Book.objects.create(name="Book 2", author=author2) + Book.objects.create(name="Book 3", author=author2) + Book.objects.create(name="Book 4", author=author2) + Book.objects.create(name="Book 5", author=author1) + library1 = Library.objects.create(name="Library 1", best_seller="Book 1") + library2 = Library.objects.create(name="Library 2", best_seller="Book 1") + library1.books.add(book1, book2) + library2.books.add(book2) + + def test_exists_subquery(self): + subquery = Book.objects.filter( + author__name=OuterRef("author__name"), author__address__city="Boston" + ) + qs = Book.objects.filter(Exists(subquery)).order_by("name") + self.assertQuerySetEqual(qs, ["Book 2", "Book 3", "Book 4"], lambda book: book.name) + + def test_in_subquery(self): + names = Book.objects.filter(author__age__gt=35).values("author__name") + qs = Book.objects.filter(author__name__in=names).order_by("name") + self.assertQuerySetEqual(qs, ["Book 2", "Book 3", "Book 4"], lambda book: book.name) + + def test_exists_with_foreign_object(self): + subquery = Library.objects.filter(best_seller=OuterRef("name")) + qs = Book.objects.filter(Exists(subquery)) + self.assertEqual(qs.first().name, "Book 1") + + def test_foreign_field_with_range(self): + qs = Library.objects.filter(books__author__age__range=(25, 35)) + self.assertEqual(qs.first().name, "Library 1") From 9b4083feacd32c9a31ed37a93801f9c62a95da52 Mon Sep 17 00:00:00 2001 From: Emanuel Lupi Date: Thu, 23 Jan 2025 17:29:08 -0500 Subject: [PATCH 2/2] add range lookup test for EmbeddedModelField --- tests/model_fields_/test_embedded_model.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/model_fields_/test_embedded_model.py b/tests/model_fields_/test_embedded_model.py index 57616597..dfb3a579 100644 --- a/tests/model_fields_/test_embedded_model.py +++ b/tests/model_fields_/test_embedded_model.py @@ -107,6 +107,9 @@ def test_gt(self): def test_gte(self): self.assertCountEqual(Holder.objects.filter(data__integer__gte=3), self.objs[3:]) + def test_range(self): + self.assertCountEqual(Holder.objects.filter(data__integer__range=(2, 4)), self.objs[2:5]) + def test_order_by_embedded_field(self): qs = Holder.objects.filter(data__integer__gt=3).order_by("-data__integer") self.assertSequenceEqual(qs, list(reversed(self.objs[4:])))