From cdfdcf4b70bebfc68871df885387790c6afbc23c Mon Sep 17 00:00:00 2001 From: Anubhav Joshi Date: Sun, 10 Aug 2014 18:23:37 +0530 Subject: [PATCH] Fixed #23266 -- Prevented queries caused by type checking lookup values Small modifications done by committer. --- django/db/models/sql/query.py | 15 +++++++++++++-- tests/queries/tests.py | 4 ++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 89fba2b56a..a590f2796e 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -1104,8 +1104,19 @@ class Query(object): if field.rel: # testing for iterable of models if hasattr(value, '__iter__'): - for v in value: - self.check_query_object_type(v, opts) + # Check if the iterable has a model attribute, if so + # it is likely something like a QuerySet. + if hasattr(value, 'model') and hasattr(value.model, '_meta'): + model = value.model + if not (model == opts.concrete_model + or opts.concrete_model in model._meta.get_parent_list() + or model in opts.get_parent_list()): + raise ValueError( + 'Cannot use QuerySet for "%s": Use a QuerySet for "%s".' % + (model._meta.model_name, opts.object_name)) + else: + for v in value: + self.check_query_object_type(v, opts) else: # expecting single model instance here self.check_query_object_type(value, opts) diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 380d64b8f9..e7dd7fab74 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -3461,6 +3461,10 @@ class RelatedLookupTypeTests(TestCase): # parent objects self.assertQuerysetEqual(ObjectC.objects.exclude(childobjecta=self.oa), out_c) + # Test for #23226 + with self.assertNumQueries(0): + ObjectB.objects.filter(objecta__in=ObjectA.objects.all()) + class Ticket14056Tests(TestCase): def test_ticket_14056(self):