summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHasan Ramezani <hasan.r67@gmail.com>2019-12-09 12:55:12 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-12-09 15:45:18 +0100
commit4540842bc385a60cf32970a8b372b80d47704bca (patch)
tree954198e362859950eb0d0679690859728de979bc
parent9e565386d3fafc8cc15d07095e50d574e5f53802 (diff)
downloaddjango-4540842bc385a60cf32970a8b372b80d47704bca.tar.gz
Fixed #31044 -- Errored nicely when using Prefetch with a raw() queryset.
-rw-r--r--django/db/models/query.py11
-rw-r--r--tests/prefetch_related/tests.py8
2 files changed, 16 insertions, 3 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 73991df7bb..764d3ea289 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -1534,8 +1534,15 @@ class Prefetch:
self.prefetch_through = lookup
# `prefetch_to` is the path to the attribute that stores the result.
self.prefetch_to = lookup
- if queryset is not None and not issubclass(queryset._iterable_class, ModelIterable):
- raise ValueError('Prefetch querysets cannot use values().')
+ if queryset is not None and (
+ isinstance(queryset, RawQuerySet) or (
+ hasattr(queryset, '_iterable_class') and
+ not issubclass(queryset._iterable_class, ModelIterable)
+ )
+ ):
+ raise ValueError(
+ 'Prefetch querysets cannot use raw() and values().'
+ )
if to_attr:
self.prefetch_to = LOOKUP_SEP.join(lookup.split(LOOKUP_SEP)[:-1] + [to_attr])
diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py
index 5b944a456b..35c2a1c6b8 100644
--- a/tests/prefetch_related/tests.py
+++ b/tests/prefetch_related/tests.py
@@ -815,12 +815,18 @@ class CustomPrefetchTests(TestCase):
self.traverse_qs(list(houses), [['occupants', 'houses', 'main_room']])
def test_values_queryset(self):
- with self.assertRaisesMessage(ValueError, 'Prefetch querysets cannot use values().'):
+ msg = 'Prefetch querysets cannot use raw() and values().'
+ with self.assertRaisesMessage(ValueError, msg):
Prefetch('houses', House.objects.values('pk'))
# That error doesn't affect managers with custom ModelIterable subclasses
self.assertIs(Teacher.objects_custom.all()._iterable_class, ModelIterableSubclass)
Prefetch('teachers', Teacher.objects_custom.all())
+ def test_raw_queryset(self):
+ msg = 'Prefetch querysets cannot use raw() and values().'
+ with self.assertRaisesMessage(ValueError, msg):
+ Prefetch('houses', House.objects.raw('select pk from house'))
+
def test_to_attr_doesnt_cache_through_attr_as_list(self):
house = House.objects.prefetch_related(
Prefetch('rooms', queryset=Room.objects.all(), to_attr='to_rooms'),