summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@gmail.com>2014-05-19 03:43:13 +0700
committerLoic Bistuer <loic.bistuer@gmail.com>2014-05-21 10:26:04 +0700
commitbdf3473e64879d196e79fe8832cdacc6efb68150 (patch)
treebde9f2c796280e89fbef915a1389295d8d43bed0 /tests
parent8a95b4fca793eeb8adceffe697b55214509019eb (diff)
Fixed #22650 -- Fixed regression on prefetch_related.
Regression from f51c1f59 when using select_related then prefetch_related on the reverse side of an O2O: Author.objects.select_related('bio').prefetch_related('bio__books') Thanks Aymeric Augustin for the report and tests. Refs #17001.
Diffstat (limited to 'tests')
-rw-r--r--tests/prefetch_related/models.py9
-rw-r--r--tests/prefetch_related/tests.py62
2 files changed, 70 insertions, 1 deletions
diff --git a/tests/prefetch_related/models.py b/tests/prefetch_related/models.py
index 8fec5d4b7b..40540e9b26 100644
--- a/tests/prefetch_related/models.py
+++ b/tests/prefetch_related/models.py
@@ -66,6 +66,11 @@ class BookWithYear(Book):
AuthorWithAge, related_name='books_with_year')
+class Bio(models.Model):
+ author = models.OneToOneField(Author)
+ books = models.ManyToManyField(Book, blank=True)
+
+
@python_2_unicode_compatible
class Reader(models.Model):
name = models.CharField(max_length=50)
@@ -196,6 +201,10 @@ class Person(models.Model):
# Assume business logic forces every person to have at least one house.
return sorted(self.houses.all(), key=lambda house: -house.rooms.count())[0]
+ @property
+ def all_houses(self):
+ return list(self.houses.all())
+
class Meta:
ordering = ['id']
diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py
index 6732e45f40..5aee9519c3 100644
--- a/tests/prefetch_related/tests.py
+++ b/tests/prefetch_related/tests.py
@@ -9,7 +9,7 @@ from django.test import TestCase, override_settings
from django.utils import six
from django.utils.encoding import force_text
-from .models import (Author, Book, Reader, Qualification, Teacher, Department,
+from .models import (Author, Bio, Book, Reader, Qualification, Teacher, Department,
TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge,
BookWithYear, BookReview, Person, House, Room, Employee, Comment,
LessonEntry, WordEntry, Author2)
@@ -192,6 +192,20 @@ class PrefetchRelatedTests(TestCase):
["Amy"],
["Amy", "Belinda"]])
+ def test_reverse_one_to_one_then_m2m(self):
+ """
+ Test that we can follow a m2m relation after going through
+ the select_related reverse of a o2o.
+ """
+ qs = Author.objects.prefetch_related('bio__books').select_related('bio')
+
+ with self.assertNumQueries(1):
+ list(qs.all())
+
+ Bio.objects.create(author=self.author1)
+ with self.assertNumQueries(2):
+ list(qs.all())
+
def test_attribute_error(self):
qs = Reader.objects.all().prefetch_related('books_read__xyz')
with self.assertRaises(AttributeError) as cm:
@@ -452,6 +466,52 @@ class CustomPrefetchTests(TestCase):
)
self.assertEqual(lst1, lst2)
+ def test_traverse_single_item_property(self):
+ # Control lookups.
+ with self.assertNumQueries(5):
+ lst1 = self.traverse_qs(
+ Person.objects.prefetch_related(
+ 'houses__rooms',
+ 'primary_house__occupants__houses',
+ ),
+ [['primary_house', 'occupants', 'houses']]
+ )
+
+ # Test lookups.
+ with self.assertNumQueries(5):
+ lst2 = self.traverse_qs(
+ Person.objects.prefetch_related(
+ 'houses__rooms',
+ Prefetch('primary_house__occupants', to_attr='occupants_lst'),
+ 'primary_house__occupants_lst__houses',
+ ),
+ [['primary_house', 'occupants_lst', 'houses']]
+ )
+ self.assertEqual(lst1, lst2)
+
+ def test_traverse_multiple_items_property(self):
+ # Control lookups.
+ with self.assertNumQueries(4):
+ lst1 = self.traverse_qs(
+ Person.objects.prefetch_related(
+ 'houses',
+ 'all_houses__occupants__houses',
+ ),
+ [['all_houses', 'occupants', 'houses']]
+ )
+
+ # Test lookups.
+ with self.assertNumQueries(4):
+ lst2 = self.traverse_qs(
+ Person.objects.prefetch_related(
+ 'houses',
+ Prefetch('all_houses__occupants', to_attr='occupants_lst'),
+ 'all_houses__occupants_lst__houses',
+ ),
+ [['all_houses', 'occupants_lst', 'houses']]
+ )
+ self.assertEqual(lst1, lst2)
+
def test_custom_qs(self):
# Test basic.
with self.assertNumQueries(2):