فهرست منبع

Fixed #24752 -- query crash when reusing Case expressions

Case expressions weren't copied deep enough (self.cases list was
reused resulting in an error).
Anssi Kääriäinen 10 سال پیش
والد
کامیت
7b05d2fdae
3فایلهای تغییر یافته به همراه20 افزوده شده و 0 حذف شده
  1. 5 0
      django/db/models/expressions.py
  2. 3 0
      docs/releases/1.8.2.txt
  3. 12 0
      tests/expressions_case/tests.py

+ 5 - 0
django/db/models/expressions.py

@@ -780,6 +780,11 @@ class Case(Expression):
         c.default = c.default.resolve_expression(query, allow_joins, reuse, summarize, for_save)
         return c
 
+    def copy(self):
+        c = super(Case, self).copy()
+        c.cases = c.cases[:]
+        return c
+
     def as_sql(self, compiler, connection, template=None, extra=None):
         connection.ops.check_expression_support(self)
         if not self.cases:

+ 3 - 0
docs/releases/1.8.2.txt

@@ -10,3 +10,6 @@ Bugfixes
 ========
 
 * Fixed check for template engine alias uniqueness (:ticket:`24685`).
+
+* Fixed crash when reusing the same ``Case`` instance in a query
+  (:ticket:`24752`).

+ 12 - 0
tests/expressions_case/tests.py

@@ -274,6 +274,18 @@ class CaseExpressionTests(TestCase):
             transform=attrgetter('integer', 'integer2')
         )
 
+    def test_case_reuse(self):
+        SOME_CASE = Case(
+            When(pk=0, then=Value('0')),
+            default=Value('1'),
+            output_field=models.CharField(),
+        )
+        self.assertQuerysetEqual(
+            CaseTestModel.objects.annotate(somecase=SOME_CASE).order_by('pk'),
+            CaseTestModel.objects.annotate(somecase=SOME_CASE).order_by('pk').values_list('pk', 'somecase'),
+            lambda x: (x.pk, x.somecase)
+        )
+
     def test_aggregate(self):
         self.assertEqual(
             CaseTestModel.objects.aggregate(