Bläddra i källkod

Fixed #25185 -- Added support for functools.partial serialization in migrations

Piper Merriam 9 år sedan
förälder
incheckning
537818af87

+ 17 - 0
django/db/migrations/writer.py

@@ -3,6 +3,7 @@ from __future__ import unicode_literals
 import collections
 import datetime
 import decimal
+import functools
 import math
 import os
 import re
@@ -439,6 +440,22 @@ class MigrationWriter(object):
             string, imports = OperationWriter(value, indentation=0).serialize()
             # Nested operation, trailing comma is handled in upper OperationWriter._write()
             return string.rstrip(','), imports
+        elif isinstance(value, functools.partial):
+            imports = {'import functools'}
+            # Serialize functools.partial() arguments
+            func_string, func_imports = cls.serialize(value.func)
+            args_string, args_imports = cls.serialize(value.args)
+            keywords_string, keywords_imports = cls.serialize(value.keywords)
+            # Add any imports needed by arguments
+            imports.update(func_imports)
+            imports.update(args_imports)
+            imports.update(keywords_imports)
+            return (
+                "functools.partial(%s, *%s, **%s)" % (
+                    func_string, args_string, keywords_string,
+                ),
+                imports,
+            )
         # Anything that knows how to deconstruct itself.
         elif hasattr(value, 'deconstruct'):
             return cls.serialize_deconstructed(*value.deconstruct())

+ 2 - 0
docs/releases/1.9.txt

@@ -385,6 +385,8 @@ Migrations
   :djadminopt:`migrate --fake-initial <--fake-initial>` to more easily detect
   initial migrations.
 
+* Added support for serialization of ``functools.partial`` objects.
+
 Models
 ^^^^^^
 

+ 6 - 0
docs/topics/migrations.txt

@@ -652,11 +652,17 @@ Django can serialize the following:
 - ``datetime.date``, ``datetime.time``, and ``datetime.datetime`` instances
   (include those that are timezone-aware)
 - ``decimal.Decimal`` instances
+- ``functools.partial`` instances which have serializable ``func``, ``args``,
+  and ``keywords`` values.
 - Any Django field
 - Any function or method reference (e.g. ``datetime.datetime.today``) (must be in module's top-level scope)
 - Any class reference (must be in module's top-level scope)
 - Anything with a custom ``deconstruct()`` method (:ref:`see below <custom-deconstruct-method>`)
 
+.. versionchanged:: 1.9
+
+    Serialization support for `functools.partial` was added.
+
 Django can serialize the following on Python 3 only:
 
 - Unbound methods used from within the class body (see below)

+ 8 - 0
tests/migrations/test_writer.py

@@ -2,6 +2,7 @@
 from __future__ import unicode_literals
 
 import datetime
+import functools
 import math
 import os
 import re
@@ -414,6 +415,13 @@ class WriterTests(SimpleTestCase):
         self.assertSerializedEqual(datetime.timedelta())
         self.assertSerializedEqual(datetime.timedelta(minutes=42))
 
+    def test_serialize_functools_partial(self):
+        value = functools.partial(datetime.timedelta, 1, seconds=2)
+        result = self.serialize_round_trip(value)
+        self.assertEqual(result.func, value.func)
+        self.assertEqual(result.args, value.args)
+        self.assertEqual(result.keywords, value.keywords)
+
     def test_simple_migration(self):
         """
         Tests serializing a simple migration.