瀏覽代碼

Fixed #33229 -- Fixed BaseDatabaseOperations.adapt_datetimefield_value()/adapt_timefield_value() crash with expressions.

SwastikTripathi 3 年之前
父節點
當前提交
a7e7043c87
共有 2 個文件被更改,包括 18 次插入2 次删除
  1. 8 0
      django/db/backends/base/operations.py
  2. 10 2
      tests/backends/base/test_operations.py

+ 8 - 0
django/db/backends/base/operations.py

@@ -505,6 +505,10 @@ class BaseDatabaseOperations:
         """
         if value is None:
             return None
+        # Expression values are adapted by the database.
+        if hasattr(value, 'resolve_expression'):
+            return value
+
         return str(value)
 
     def adapt_timefield_value(self, value):
@@ -514,6 +518,10 @@ class BaseDatabaseOperations:
         """
         if value is None:
             return None
+        # Expression values are adapted by the database.
+        if hasattr(value, 'resolve_expression'):
+            return value
+
         if timezone.is_aware(value):
             raise ValueError("Django does not support timezone-aware times.")
         return str(value)

+ 10 - 2
tests/backends/base/test_operations.py

@@ -3,7 +3,7 @@ import decimal
 from django.core.management.color import no_style
 from django.db import NotSupportedError, connection, transaction
 from django.db.backends.base.operations import BaseDatabaseOperations
-from django.db.models import DurationField
+from django.db.models import DurationField, Value
 from django.test import (
     SimpleTestCase, TestCase, TransactionTestCase, override_settings,
     skipIfDBFeature,
@@ -72,9 +72,17 @@ class SimpleDatabaseOperationTests(SimpleTestCase):
     def test_adapt_timefield_value_none(self):
         self.assertIsNone(self.ops.adapt_timefield_value(None))
 
-    def test_adapt_datetimefield_value(self):
+    def test_adapt_timefield_value_expression(self):
+        value = Value(timezone.now().time())
+        self.assertEqual(self.ops.adapt_timefield_value(value), value)
+
+    def test_adapt_datetimefield_value_none(self):
         self.assertIsNone(self.ops.adapt_datetimefield_value(None))
 
+    def test_adapt_datetimefield_value_expression(self):
+        value = Value(timezone.now())
+        self.assertEqual(self.ops.adapt_datetimefield_value(value), value)
+
     def test_adapt_timefield_value(self):
         msg = 'Django does not support timezone-aware times.'
         with self.assertRaisesMessage(ValueError, msg):