Fixed #23950 -- Prevented calling deconstruct on classes in MigrationWriter.
This commit is contained in:
parent
9d1a69579b
commit
dee4d23f7e
|
@ -330,6 +330,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())
|
||||
|
@ -364,20 +378,6 @@ class MigrationWriter(object):
|
|||
"https://docs.djangoproject.com/en/dev/topics/migrations/#serializing-values"
|
||||
% (value.__name__, module_name))
|
||||
return "%s.%s" % (module_name, value.__name__), {"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__), {"import %s" % module}
|
||||
# Other iterables
|
||||
elif isinstance(value, collections.Iterable):
|
||||
imports = set()
|
||||
|
|
|
@ -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`).
|
||||
|
|
|
@ -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…
Reference in New Issue