diff options
| author | Hasan Ramezani <hasan.r67@gmail.com> | 2019-10-10 21:13:21 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-10-11 08:10:48 +0200 |
| commit | 6a75cea76a98c08bf2e20d787be9b14c2cd94860 (patch) | |
| tree | 91c8d04ed510c2c0c75a0f2e5396882760d95891 | |
| parent | e1ae2b00504ba30481285b2bd767d1ad561bf4be (diff) | |
Fixed #30854 -- Fixed QuerySet.select_related() with multiple FilteredRelations.
| -rw-r--r-- | django/db/models/sql/compiler.py | 9 | ||||
| -rw-r--r-- | tests/filtered_relation/tests.py | 12 |
2 files changed, 17 insertions, 4 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index f475b82921..9493d0dc3c 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -1,5 +1,6 @@ import collections import re +from functools import partial from itertools import chain from django.core.exceptions import EmptyResultSet, FieldError @@ -896,6 +897,9 @@ class SQLCompiler: if from_obj: f.remote_field.set_cached_value(from_obj, obj) + 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: @@ -906,15 +910,12 @@ class SQLCompiler: model = join_opts.model alias = joins[-1] from_parent = issubclass(model, opts.model) and model is not opts.model - - 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) diff --git a/tests/filtered_relation/tests.py b/tests/filtered_relation/tests.py index 48154413a5..05869a2a95 100644 --- a/tests/filtered_relation/tests.py +++ b/tests/filtered_relation/tests.py @@ -52,6 +52,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)), |
