Jelajahi Sumber

Fixed qs.values() regression when used in subquery

Anssi Kääriäinen 12 tahun lalu
induk
melakukan
f53059b411
2 mengubah file dengan 23 tambahan dan 1 penghapusan
  1. 6 1
      django/db/models/sql/where.py
  2. 17 0
      tests/queries/tests.py

+ 6 - 1
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)

+ 17 - 0
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)