[3.0.x] Fixed #30854 -- Fixed QuerySet.select_related() with multiple FilteredRelations.

Backport of 6a75cea76a from master.
This commit is contained in:
Hasan Ramezani 2019-10-10 21:13:21 +02:00 committed by Mariusz Felisiak
parent 0dede9e981
commit c1cfec6b50
2 changed files with 18 additions and 4 deletions

View File

@ -1,6 +1,7 @@
import collections
import re
import warnings
from functools import partial
from itertools import chain
from django.core.exceptions import EmptyResultSet, FieldError
@ -902,6 +903,10 @@ class SQLCompiler:
select, model._meta, alias, cur_depth + 1,
next, restricted)
get_related_klass_infos(klass_info, next_klass_infos)
def remote_setter(name, obj, from_obj):
setattr(from_obj, name, obj)
for name in list(requested):
# Filtered relations work only on the topmost level.
if cur_depth > 1:
@ -917,15 +922,12 @@ class SQLCompiler:
# Set a reverse fk object when relation is non-empty.
if from_obj:
f.remote_field.set_cached_value(from_obj, obj)
def remote_setter(obj, from_obj):
setattr(from_obj, name, obj)
klass_info = {
'model': model,
'field': f,
'reverse': True,
'local_setter': local_setter,
'remote_setter': remote_setter,
'remote_setter': partial(remote_setter, name),
'from_parent': from_parent,
}
related_klass_infos.append(klass_info)

View File

@ -50,6 +50,18 @@ class FilteredRelationTests(TestCase):
(self.author2, self.book3, self.editor_b, self.author2),
], lambda x: (x, x.book_join, x.book_join.editor, x.book_join.author))
def test_select_related_multiple(self):
qs = Book.objects.annotate(
author_join=FilteredRelation('author'),
editor_join=FilteredRelation('editor'),
).select_related('author_join', 'editor_join').order_by('pk')
self.assertQuerysetEqual(qs, [
(self.book1, self.author1, self.editor_a),
(self.book2, self.author2, self.editor_b),
(self.book3, self.author2, self.editor_b),
(self.book4, self.author1, self.editor_a),
], lambda x: (x, x.author_join, x.editor_join))
def test_select_related_with_empty_relation(self):
qs = Author.objects.annotate(
book_join=FilteredRelation('book', condition=Q(pk=-1)),