summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/migrations/writer.py28
-rw-r--r--docs/releases/1.7.2.txt3
-rw-r--r--tests/migrations/test_writer.py11
3 files changed, 28 insertions, 14 deletions
diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py
index 53ec414335..074a615afe 100644
--- a/django/db/migrations/writer.py
+++ b/django/db/migrations/writer.py
@@ -329,6 +329,20 @@ class MigrationWriter(object):
elif isinstance(value, models.Field):
attr_name, path, args, kwargs = value.deconstruct()
return cls.serialize_deconstructed(path, args, kwargs)
+ # Classes
+ elif isinstance(value, type):
+ special_cases = [
+ (models.Model, "models.Model", []),
+ ]
+ for case, string, imports in special_cases:
+ if case is value:
+ return string, set(imports)
+ if hasattr(value, "__module__"):
+ module = value.__module__
+ if module == six.moves.builtins.__name__:
+ return value.__name__, set()
+ else:
+ return "%s.%s" % (module, value.__name__), {"import %s" % module}
# Anything that knows how to deconstruct itself.
elif hasattr(value, 'deconstruct'):
return cls.serialize_deconstructed(*value.deconstruct())
@@ -362,20 +376,6 @@ class MigrationWriter(object):
"For more information, see https://docs.djangoproject.com/en/1.7/topics/migrations/#serializing-values"
% (value.__name__, module_name))
return "%s.%s" % (module_name, value.__name__), set(["import %s" % module_name])
- # Classes
- elif isinstance(value, type):
- special_cases = [
- (models.Model, "models.Model", []),
- ]
- for case, string, imports in special_cases:
- if case is value:
- return string, set(imports)
- if hasattr(value, "__module__"):
- module = value.__module__
- if module == six.moves.builtins.__name__:
- return value.__name__, set()
- else:
- return "%s.%s" % (module, value.__name__), set(["import %s" % module])
# Other iterables
elif isinstance(value, collections.Iterable):
imports = set()
diff --git a/docs/releases/1.7.2.txt b/docs/releases/1.7.2.txt
index 39e89a25d1..a537207924 100644
--- a/docs/releases/1.7.2.txt
+++ b/docs/releases/1.7.2.txt
@@ -101,3 +101,6 @@ Bugfixes
* Fixed ``runserver`` crash when socket error message contained Unicode
characters (:ticket:`23946`).
+
+* Fixed serialization of ``type`` when adding a ``deconstruct()`` method
+ (:ticket:`23950`).
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index cb9ed5d0d5..dc551acc6b 100644
--- a/tests/migrations/test_writer.py
+++ b/tests/migrations/test_writer.py
@@ -340,3 +340,14 @@ class WriterTests(TestCase):
fixed_offset_datetime = datetime.datetime(2014, 1, 1, 1, 1, tzinfo=FixedOffset(180))
self.assertEqual(MigrationWriter.serialize_datetime(fixed_offset_datetime),
"datetime.datetime(2013, 12, 31, 22, 1, tzinfo=utc)")
+
+ def test_deconstruct_class_arguments(self):
+ # Yes, it doesn't make sense to use a class as a default for a
+ # CharField. It does make sense for custom fields though, for example
+ # an enumfield that takes the enum class as an argument.
+ class DeconstructableInstances(object):
+ def deconstruct(self):
+ return ('DeconstructableInstances', [], {})
+
+ string = MigrationWriter.serialize(models.CharField(default=DeconstructableInstances))[0]
+ self.assertEqual(string, "models.CharField(default=migrations.test_writer.DeconstructableInstances)")