#22650 closed Bug (fixed)
Regression from f51c1f59 with select_related + prefetch_related
Description ¶
If a queryset does:
- select_related through a reverse one-to-one
- prefetch_related through that one-to-one then another relation
and some objects don't have a related object through the reverse one-to-one, iterating the queryset raises an exception.
This is easier to demonstrate with a test case:
-
TabularUnified tests/prefetch_related/models.py
diff --git a/tests/prefetch_related/models.py b/tests/prefetch_related/models.py index 8fec5d4..ef2eeb7 100644
a b class BookWithYear(Book): 66 66 AuthorWithAge, related_name='books_with_year') 67 67 68 68 69 class Bio(models.Model): 70 author = models.OneToOneField(Author) 71 books = models.ManyToManyField(Book, blank=True) 72 73 69 74 @python_2_unicode_compatible 70 75 class Reader(models.Model): 71 76 name = models.CharField(max_length=50) -
TabularUnified tests/prefetch_related/tests.py
diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index 6732e45..0cdd8db 100644
a b from django.test import TestCase, override_settings 9 9 from django.utils import six 10 10 from django.utils.encoding import force_text 11 11 12 from .models import (Author, B ook, Reader, Qualification, Teacher, Department,12 from .models import (Author, Bio, Book, Reader, Qualification, Teacher, Department, 13 13 TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge, 14 14 BookWithYear, BookReview, Person, House, Room, Employee, Comment, 15 15 LessonEntry, WordEntry, Author2) … … class PrefetchRelatedTests(TestCase): 192 192 ["Amy"], 193 193 ["Amy", "Belinda"]]) 194 194 195 def test_reverse_one_to_one_then_m2m(self): 196 list(Author.objects.prefetch_related('bio__books').select_related('bio')) 197 195 198 def test_attribute_error(self): 196 199 qs = Reader.objects.all().prefetch_related('books_read__xyz') 197 200 with self.assertRaises(AttributeError) as cm:
This test fails with:
Traceback (most recent call last): File "/Users/myk/Documents/dev/django/tests/prefetch_related/tests.py", line 196, in test_reverse_one_to_one_then_m2m list(Author.objects.prefetch_related('bio__books').select_related('bio')) File "/Users/myk/Documents/dev/django/django/db/models/query.py", line 141, in __iter__ self._fetch_all() File "/Users/myk/Documents/dev/django/django/db/models/query.py", line 965, in _fetch_all self._prefetch_related_objects() File "/Users/myk/Documents/dev/django/django/db/models/query.py", line 608, in _prefetch_related_objects prefetch_related_objects(self._result_cache, self._prefetch_related_lookups) File "/Users/myk/Documents/dev/django/django/db/models/query.py", line 1793, in prefetch_related_objects elif isinstance(getattr(first_obj, through_attr), list): File "/Users/myk/Documents/dev/django/django/db/models/fields/related.py", line 420, in __get__ self.related.get_accessor_name() RelatedObjectDoesNotExist: Author has no bio.
The regression exists in master and 1.7.x.
Change History (10)
comment:1 by , 11 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 11 years ago
Version: | master → 1.7-beta-2 |
---|
comment:3 by , 11 years ago
Has patch: | set |
---|
comment:4 by , 11 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:5 by , 11 years ago
Patch needs improvement: | set |
---|---|
Triage Stage: | Ready for checkin → Accepted |
Actually tests don't pass on Python 3.
comment:6 by , 11 years ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
comment:7 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.
PR https://github.com/django/django/pull/2681.