mirror of
				https://github.com/django/django.git
				synced 2025-10-30 09:06:13 +00:00 
			
		
		
		
	[1.6.x] Fixed #21760 -- prefetch_related used an inefficient query for reverse FK.
Regression introduced by commit9777442. Refs #21410. Conflicts: tests/prefetch_related/tests.py Backport ofd3b71b976dfrom master
This commit is contained in:
		
							
								
								
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -599,6 +599,7 @@ answer newbie questions, and generally made Django that much better: | |||||||
|     David Tulig <david.tulig@gmail.com> |     David Tulig <david.tulig@gmail.com> | ||||||
|     Justine Tunney <jtunney@lobstertech.com> |     Justine Tunney <jtunney@lobstertech.com> | ||||||
|     Amit Upadhyay <http://www.amitu.com/blog/> |     Amit Upadhyay <http://www.amitu.com/blog/> | ||||||
|  |     valtron | ||||||
|     Adam Vandenberg |     Adam Vandenberg | ||||||
|     Geert Vanderkelen |     Geert Vanderkelen | ||||||
|     Vasil Vangelovski |     Vasil Vangelovski | ||||||
|   | |||||||
| @@ -279,7 +279,9 @@ class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjec | |||||||
|         # composite fields. In the meantime we take this practical approach to |         # composite fields. In the meantime we take this practical approach to | ||||||
|         # solve a regression on 1.6 when the reverse manager in hidden |         # solve a regression on 1.6 when the reverse manager in hidden | ||||||
|         # (related_name ends with a '+'). Refs #21410. |         # (related_name ends with a '+'). Refs #21410. | ||||||
|         if self.field.rel.is_hidden(): |         # The check for len(...) == 1 is a special case that allows the query | ||||||
|  |         # to be join-less and smaller. Refs #21760. | ||||||
|  |         if self.field.rel.is_hidden() or len(self.field.foreign_related_fields) == 1: | ||||||
|             query = {'%s__in' % related_field.name: set(instance_attr(inst)[0] for inst in instances)} |             query = {'%s__in' % related_field.name: set(instance_attr(inst)[0] for inst in instances)} | ||||||
|         else: |         else: | ||||||
|             query = {'%s__in' % self.field.related_query_name(): instances} |             query = {'%s__in' % self.field.related_query_name(): instances} | ||||||
|   | |||||||
| @@ -67,5 +67,9 @@ Other bugfixes and changes | |||||||
| * Fixed :djadmin:`changepassword` on Windows | * Fixed :djadmin:`changepassword` on Windows | ||||||
|   (`#22364 <https://code.djangoproject.com/ticket/22364>`_). |   (`#22364 <https://code.djangoproject.com/ticket/22364>`_). | ||||||
|  |  | ||||||
|  | * Fixed regression in ``prefetch_related`` that caused the related objects | ||||||
|  |   query to include an unnecessary join | ||||||
|  |   (`#21760 <https://code.djangoproject.com/ticket/21760>`_). | ||||||
|  |  | ||||||
| Additionally, Django's vendored version of six, :mod:`django.utils.six` has been | Additionally, Django's vendored version of six, :mod:`django.utils.six` has been | ||||||
| upgraded to the latest release (1.6.1). | upgraded to the latest release (1.6.1). | ||||||
|   | |||||||
| @@ -2,9 +2,11 @@ from __future__ import absolute_import, unicode_literals | |||||||
|  |  | ||||||
| from django.contrib.contenttypes.models import ContentType | from django.contrib.contenttypes.models import ContentType | ||||||
| from django.db import connection | from django.db import connection | ||||||
|  | from django.db.models.query import get_prefetcher | ||||||
| from django.test import TestCase | from django.test import TestCase | ||||||
| from django.test.utils import override_settings | from django.test.utils import override_settings | ||||||
| from django.utils import six | 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, Book, Reader, Qualification, Teacher, Department, | ||||||
|     TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge, |     TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge, | ||||||
| @@ -677,3 +679,18 @@ class Ticket21410Tests(TestCase): | |||||||
|  |  | ||||||
|     def test_bug(self): |     def test_bug(self): | ||||||
|         list(Author2.objects.prefetch_related('first_book', 'favorite_books')) |         list(Author2.objects.prefetch_related('first_book', 'favorite_books')) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Ticket21760Tests(TestCase): | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         self.rooms = [] | ||||||
|  |         for _ in range(3): | ||||||
|  |             house = House.objects.create() | ||||||
|  |             for _ in range(3): | ||||||
|  |                 self.rooms.append(Room.objects.create(house = house)) | ||||||
|  |  | ||||||
|  |     def test_bug(self): | ||||||
|  |         prefetcher = get_prefetcher(self.rooms[0], 'house')[0] | ||||||
|  |         queryset = prefetcher.get_prefetch_queryset(list(Room.objects.all()))[0] | ||||||
|  |         self.assertNotIn(' JOIN ', force_text(queryset.query)) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user