diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py index ff3d1bdcfb..08f9d6c837 100644 --- a/django/db/models/sql/where.py +++ b/django/db/models/sql/where.py @@ -399,7 +399,12 @@ class SubqueryConstraint(object): if hasattr(query, 'values'): if query._db and connection.alias != query._db: raise ValueError("Can't do subqueries with queries on different DBs.") - query = query.values(*self.targets).query + # Do not override already existing values. + if not hasattr(query, 'field_names'): + query = query.values(*self.targets) + else: + query = query._clone() + query = query.query query.clear_ordering(True) query_compiler = query.get_compiler(connection=connection) diff --git a/tests/queries/tests.py b/tests/queries/tests.py index cdc26248c9..ad5dde34b5 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -2831,3 +2831,20 @@ class EmptyStringPromotionTests(TestCase): self.assertIn('LEFT OUTER JOIN', str(qs.query)) else: self.assertNotIn('LEFT OUTER JOIN', str(qs.query)) + +class ValuesSubqueryTests(TestCase): + def test_values_in_subquery(self): + # Check that if a values() queryset is used, then the given values + # will be used instead of forcing use of the relation's field. + o1 = Order.objects.create(id=-2) + o2 = Order.objects.create(id=-1) + oi1 = OrderItem.objects.create(order=o1, status=0) + oi1.status = oi1.pk + oi1.save() + OrderItem.objects.create(order=o2, status=0) + + # The query below should match o1 as it has related order_item + # with id == status. + self.assertQuerysetEqual( + Order.objects.filter(items__in=OrderItem.objects.values_list('status')), + [o1.pk], lambda x: x.pk)