summaryrefslogtreecommitdiff
path: root/tests/many_to_many
diff options
context:
space:
mode:
authoroliver <myungsekyo@gmail.com>2018-10-16 00:01:57 +0900
committerTim Graham <timograham@gmail.com>2018-10-15 11:01:57 -0400
commit1299421cadc4fcf63585f2f88337078e43e660e0 (patch)
tree967626dd556d13de83fc6352ea0fb9eb003da8a3 /tests/many_to_many
parentf2e2a1bd4be8ec7624b081488292b804777a526a (diff)
downloaddjango-1299421cadc4fcf63585f2f88337078e43e660e0.tar.gz
Fixed #29725 -- Removed unnecessary join in QuerySet.count() and exists() on a many-to-many relation.
Diffstat (limited to 'tests/many_to_many')
-rw-r--r--tests/many_to_many/models.py10
-rw-r--r--tests/many_to_many/tests.py46
2 files changed, 53 insertions, 3 deletions
diff --git a/tests/many_to_many/models.py b/tests/many_to_many/models.py
index 22911654ab..7047a4e5d0 100644
--- a/tests/many_to_many/models.py
+++ b/tests/many_to_many/models.py
@@ -55,3 +55,13 @@ class InheritedArticleA(AbstractArticle):
class InheritedArticleB(AbstractArticle):
pass
+
+
+class NullableTargetArticle(models.Model):
+ headline = models.CharField(max_length=100)
+ publications = models.ManyToManyField(Publication, through='NullablePublicationThrough')
+
+
+class NullablePublicationThrough(models.Model):
+ article = models.ForeignKey(NullableTargetArticle, models.CASCADE)
+ publication = models.ForeignKey(Publication, models.CASCADE, null=True)
diff --git a/tests/many_to_many/tests.py b/tests/many_to_many/tests.py
index 5360b978c2..933eb23a7a 100644
--- a/tests/many_to_many/tests.py
+++ b/tests/many_to_many/tests.py
@@ -1,7 +1,13 @@
-from django.db import transaction
-from django.test import TestCase
+from unittest import mock
-from .models import Article, InheritedArticleA, InheritedArticleB, Publication
+from django.db import connection, transaction
+from django.test import TestCase, skipUnlessDBFeature
+from django.test.utils import CaptureQueriesContext
+
+from .models import (
+ Article, InheritedArticleA, InheritedArticleB, NullablePublicationThrough,
+ NullableTargetArticle, Publication,
+)
class ManyToManyTests(TestCase):
@@ -554,3 +560,37 @@ class ManyToManyTests(TestCase):
]
)
self.assertQuerysetEqual(b.publications.all(), ['<Publication: Science Weekly>'])
+
+
+class ManyToManyQueryTests(TestCase):
+ @classmethod
+ def setUpTestData(cls):
+ cls.article = Article.objects.create(headline='Django lets you build Web apps easily')
+ cls.nullable_target_article = NullableTargetArticle.objects.create(headline='The python is good')
+ NullablePublicationThrough.objects.create(article=cls.nullable_target_article, publication=None)
+
+ @skipUnlessDBFeature('supports_foreign_keys')
+ def test_count_join_optimization(self):
+ with CaptureQueriesContext(connection) as query:
+ self.article.publications.count()
+ self.assertNotIn('JOIN', query[0]['sql'])
+ self.assertEqual(self.nullable_target_article.publications.count(), 0)
+
+ def test_count_join_optimization_disabled(self):
+ with mock.patch.object(connection.features, 'supports_foreign_keys', False), \
+ CaptureQueriesContext(connection) as query:
+ self.article.publications.count()
+ self.assertIn('JOIN', query[0]['sql'])
+
+ @skipUnlessDBFeature('supports_foreign_keys')
+ def test_exists_join_optimization(self):
+ with CaptureQueriesContext(connection) as query:
+ self.article.publications.exists()
+ self.assertNotIn('JOIN', query[0]['sql'])
+ self.assertIs(self.nullable_target_article.publications.exists(), False)
+
+ def test_exists_join_optimization_disabled(self):
+ with mock.patch.object(connection.features, 'supports_foreign_keys', False), \
+ CaptureQueriesContext(connection) as query:
+ self.article.publications.exists()
+ self.assertIn('JOIN', query[0]['sql'])