Loading django/db/migrations/writer.py +14 −14 Original line number Diff line number Diff line Loading @@ -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()) Loading Loading @@ -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() Loading docs/releases/1.7.2.txt +3 −0 Original line number Diff line number Diff line Loading @@ -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`). tests/migrations/test_writer.py +11 −0 Original line number Diff line number Diff line Loading @@ -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)") Loading
django/db/migrations/writer.py +14 −14 Original line number Diff line number Diff line Loading @@ -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()) Loading Loading @@ -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() Loading
docs/releases/1.7.2.txt +3 −0 Original line number Diff line number Diff line Loading @@ -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`).
tests/migrations/test_writer.py +11 −0 Original line number Diff line number Diff line Loading @@ -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)")