Loading django/db/migrations/writer.py +17 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ from __future__ import unicode_literals import collections import datetime import decimal import functools import math import os import re Loading Loading @@ -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()) Loading docs/releases/1.9.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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 ^^^^^^ Loading docs/topics/migrations.txt +6 −0 Original line number Diff line number Diff line Loading @@ -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) Loading tests/migrations/test_writer.py +8 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ from __future__ import unicode_literals import datetime import functools import math import os import re Loading Loading @@ -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. Loading Loading
django/db/migrations/writer.py +17 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ from __future__ import unicode_literals import collections import datetime import decimal import functools import math import os import re Loading Loading @@ -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()) Loading
docs/releases/1.9.txt +2 −0 Original line number Diff line number Diff line Loading @@ -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 ^^^^^^ Loading
docs/topics/migrations.txt +6 −0 Original line number Diff line number Diff line Loading @@ -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) Loading
tests/migrations/test_writer.py +8 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ from __future__ import unicode_literals import datetime import functools import math import os import re Loading Loading @@ -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. Loading