Loading django/db/models/query.py +7 −2 Original line number Diff line number Diff line Loading @@ -1558,8 +1558,13 @@ def prefetch_related_objects(result_cache, related_lookups): good_objects = False break else: # We already did this list break # Since prefetching can re-use instances, it is possible to # have the same instance multiple times in obj_list. So we # can reach this branch either because we did all of # obj_list already, or because we did 'obj' earlier in this # iteration over obj_list. In the first case we could # shortcut and exit the loop, but not in the second. continue if not good_objects: break Loading tests/prefetch_related/models.py +20 −0 Original line number Diff line number Diff line Loading @@ -195,3 +195,23 @@ class Employee(models.Model): class Meta: ordering = ['id'] ### Ticket 19607 @python_2_unicode_compatible class LessonEntry(models.Model): name1 = models.CharField(max_length=200) name2 = models.CharField(max_length=200) def __str__(self): return "%s %s" % (self.name1, self.name2) @python_2_unicode_compatible class WordEntry(models.Model): lesson_entry = models.ForeignKey(LessonEntry) name = models.CharField(max_length=200) def __str__(self): return "%s (%s)" % (self.name, self.id) tests/prefetch_related/tests.py +24 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,8 @@ from django.utils import six from .models import (Author, Book, Reader, Qualification, Teacher, Department, TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge, BookWithYear, BookReview, Person, House, Room, Employee, Comment) BookWithYear, BookReview, Person, House, Room, Employee, Comment, LessonEntry, WordEntry) class PrefetchRelatedTests(TestCase): Loading Loading @@ -618,3 +619,25 @@ class MultiDbTests(TestCase): ages = ", ".join(str(a.authorwithage.age) for a in A.prefetch_related('authorwithage')) self.assertEqual(ages, "50, 49") class Ticket19607Tests(TestCase): def setUp(self): for id, name1, name2 in [ (1, 'einfach', 'simple'), (2, 'schwierig', 'difficult'), ]: LessonEntry.objects.create(id=id, name1=name1, name2=name2) for id, lesson_entry_id, name in [ (1, 1, 'einfach'), (2, 1, 'simple'), (3, 2, 'schwierig'), (4, 2, 'difficult'), ]: WordEntry.objects.create(id=id, lesson_entry_id=lesson_entry_id, name=name) def test_bug(self): list(WordEntry.objects.prefetch_related('lesson_entry', 'lesson_entry__wordentry_set')) Loading
django/db/models/query.py +7 −2 Original line number Diff line number Diff line Loading @@ -1558,8 +1558,13 @@ def prefetch_related_objects(result_cache, related_lookups): good_objects = False break else: # We already did this list break # Since prefetching can re-use instances, it is possible to # have the same instance multiple times in obj_list. So we # can reach this branch either because we did all of # obj_list already, or because we did 'obj' earlier in this # iteration over obj_list. In the first case we could # shortcut and exit the loop, but not in the second. continue if not good_objects: break Loading
tests/prefetch_related/models.py +20 −0 Original line number Diff line number Diff line Loading @@ -195,3 +195,23 @@ class Employee(models.Model): class Meta: ordering = ['id'] ### Ticket 19607 @python_2_unicode_compatible class LessonEntry(models.Model): name1 = models.CharField(max_length=200) name2 = models.CharField(max_length=200) def __str__(self): return "%s %s" % (self.name1, self.name2) @python_2_unicode_compatible class WordEntry(models.Model): lesson_entry = models.ForeignKey(LessonEntry) name = models.CharField(max_length=200) def __str__(self): return "%s (%s)" % (self.name, self.id)
tests/prefetch_related/tests.py +24 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,8 @@ from django.utils import six from .models import (Author, Book, Reader, Qualification, Teacher, Department, TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge, BookWithYear, BookReview, Person, House, Room, Employee, Comment) BookWithYear, BookReview, Person, House, Room, Employee, Comment, LessonEntry, WordEntry) class PrefetchRelatedTests(TestCase): Loading Loading @@ -618,3 +619,25 @@ class MultiDbTests(TestCase): ages = ", ".join(str(a.authorwithage.age) for a in A.prefetch_related('authorwithage')) self.assertEqual(ages, "50, 49") class Ticket19607Tests(TestCase): def setUp(self): for id, name1, name2 in [ (1, 'einfach', 'simple'), (2, 'schwierig', 'difficult'), ]: LessonEntry.objects.create(id=id, name1=name1, name2=name2) for id, lesson_entry_id, name in [ (1, 1, 'einfach'), (2, 1, 'simple'), (3, 2, 'schwierig'), (4, 2, 'difficult'), ]: WordEntry.objects.create(id=id, lesson_entry_id=lesson_entry_id, name=name) def test_bug(self): list(WordEntry.objects.prefetch_related('lesson_entry', 'lesson_entry__wordentry_set'))