mirror of https://github.com/django/django.git
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):
|
elif isinstance(value, models.Field):
|
||||||
attr_name, path, args, kwargs = value.deconstruct()
|
attr_name, path, args, kwargs = value.deconstruct()
|
||||||
return cls.serialize_deconstructed(path, args, kwargs)
|
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.
|
# Anything that knows how to deconstruct itself.
|
||||||
elif hasattr(value, 'deconstruct'):
|
elif hasattr(value, 'deconstruct'):
|
||||||
return cls.serialize_deconstructed(*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"
|
"https://docs.djangoproject.com/en/dev/topics/migrations/#serializing-values"
|
||||||
% (value.__name__, module_name))
|
% (value.__name__, module_name))
|
||||||
return "%s.%s" % (module_name, value.__name__), {"import %s" % 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
|
# Other iterables
|
||||||
elif isinstance(value, collections.Iterable):
|
elif isinstance(value, collections.Iterable):
|
||||||
imports = set()
|
imports = set()
|
||||||
|
|
|
@ -101,3 +101,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed ``runserver`` crash when socket error message contained Unicode
|
* Fixed ``runserver`` crash when socket error message contained Unicode
|
||||||
characters (:ticket:`23946`).
|
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))
|
fixed_offset_datetime = datetime.datetime(2014, 1, 1, 1, 1, tzinfo=FixedOffset(180))
|
||||||
self.assertEqual(MigrationWriter.serialize_datetime(fixed_offset_datetime),
|
self.assertEqual(MigrationWriter.serialize_datetime(fixed_offset_datetime),
|
||||||
"datetime.datetime(2013, 12, 31, 22, 1, tzinfo=utc)")
|
"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