Browse Source

Fixed #26555 -- Gave deconstructible objects a higher priority during serialization

Markus Holtermann 9 năm trước cách đây
mục cha
commit
3b383085fb
2 tập tin đã thay đổi với 34 bổ sung11 xóa
  1. 12 11
      django/db/migrations/serializer.py
  2. 22 0
      tests/migrations/test_writer.py

+ 12 - 11
django/db/migrations/serializer.py

@@ -329,6 +329,18 @@ def serializer_factory(value):
         # tuple.
         value = value.__reduce__()[1][0]
 
+    if isinstance(value, models.Field):
+        return ModelFieldSerializer(value)
+    if isinstance(value, models.manager.BaseManager):
+        return ModelManagerSerializer(value)
+    if isinstance(value, Operation):
+        return OperationSerializer(value)
+    if isinstance(value, type):
+        return TypeSerializer(value)
+    # Anything that knows how to deconstruct itself.
+    if hasattr(value, 'deconstruct'):
+        return DeconstructableSerializer(value)
+
     # Unfortunately some of these are order-dependent.
     if isinstance(value, frozenset):
         return FrozensetSerializer(value)
@@ -362,19 +374,8 @@ def serializer_factory(value):
         return TextTypeSerializer(value)
     if isinstance(value, decimal.Decimal):
         return DecimalSerializer(value)
-    if isinstance(value, models.Field):
-        return ModelFieldSerializer(value)
-    if isinstance(value, type):
-        return TypeSerializer(value)
-    if isinstance(value, models.manager.BaseManager):
-        return ModelManagerSerializer(value)
-    if isinstance(value, Operation):
-        return OperationSerializer(value)
     if isinstance(value, functools.partial):
         return FunctoolsPartialSerializer(value)
-    # Anything that knows how to deconstruct itself.
-    if hasattr(value, 'deconstruct'):
-        return DeconstructableSerializer(value)
     if isinstance(value, (types.FunctionType, types.BuiltinFunctionType)):
         return FunctionTypeSerializer(value)
     if isinstance(value, collections.Iterable):

+ 22 - 0
tests/migrations/test_writer.py

@@ -2,6 +2,7 @@
 from __future__ import unicode_literals
 
 import datetime
+import decimal
 import functools
 import math
 import os
@@ -35,6 +36,15 @@ except ImportError:
     enum = None
 
 
+class Money(decimal.Decimal):
+    def deconstruct(self):
+        return (
+            '%s.%s' % (self.__class__.__module__, self.__class__.__name__),
+            [six.text_type(self)],
+            {}
+        )
+
+
 class TestModel1(object):
     def upload_to(self):
         return "somewhere dynamic"
@@ -200,6 +210,18 @@ class WriterTests(SimpleTestCase):
         self.assertTrue(math.isinf(self.serialize_round_trip(float("-inf"))))
         self.assertTrue(math.isnan(self.serialize_round_trip(float("nan"))))
 
+        self.assertSerializedEqual(decimal.Decimal('1.3'))
+        self.assertSerializedResultEqual(
+            decimal.Decimal('1.3'),
+            ("Decimal('1.3')", {'from decimal import Decimal'})
+        )
+
+        self.assertSerializedEqual(Money('1.3'))
+        self.assertSerializedResultEqual(
+            Money('1.3'),
+            ("migrations.test_writer.Money('1.3')", {'import migrations.test_writer'})
+        )
+
     def test_serialize_constants(self):
         self.assertSerializedEqual(None)
         self.assertSerializedEqual(True)