瀏覽代碼

Fixed #19263 -- Fixed crash when filtering using __in and an empty QuerySet.

Thanks Marcin Biernat for the initial patch and tests.
Tim Graham 9 年之前
父節點
當前提交
233b46f931
共有 2 個文件被更改,包括 13 次插入1 次删除
  1. 4 1
      django/db/models/sql/compiler.py
  2. 9 0
      tests/queries/tests.py

+ 4 - 1
django/db/models/sql/compiler.py

@@ -484,7 +484,10 @@ class SQLCompiler(object):
         if obj.low_mark == 0 and obj.high_mark is None and not self.query.distinct_fields:
             # If there is no slicing in use, then we can safely drop all ordering
             obj.clear_ordering(True)
-        return obj.get_compiler(connection=self.connection).as_sql(subquery=True)
+        nested_sql = obj.get_compiler(connection=self.connection).as_sql(subquery=True)
+        if nested_sql == ('', ()):
+            raise EmptyResultSet
+        return nested_sql
 
     def get_default_columns(self, start_alias=None, opts=None, from_parent=None):
         """

+ 9 - 0
tests/queries/tests.py

@@ -2362,6 +2362,9 @@ class WeirdQuerysetSlicingTests(BaseQuerysetTest):
         Article.objects.create(name='three', created=datetime.datetime.now())
         Article.objects.create(name='four', created=datetime.datetime.now())
 
+        food = Food.objects.create(name='spam')
+        Eaten.objects.create(meal='spam with eggs', food=food)
+
     def test_tickets_7698_10202(self):
         # People like to slice with '0' as the high-water mark.
         self.assertQuerysetEqual(Article.objects.all()[0:0], [])
@@ -2377,6 +2380,12 @@ class WeirdQuerysetSlicingTests(BaseQuerysetTest):
         # ticket #12192
         self.assertNumQueries(0, lambda: list(Number.objects.all()[1:1]))
 
+    def test_empty_sliced_subquery(self):
+        self.assertEqual(Eaten.objects.filter(food__in=Food.objects.all()[0:0]).count(), 0)
+
+    def test_empty_sliced_subquery_exclude(self):
+        self.assertEqual(Eaten.objects.exclude(food__in=Food.objects.all()[0:0]).count(), 1)
+
 
 class EscapingTests(TestCase):
     def test_ticket_7302(self):