Fixed #23226: Model options appearing as bytes type in migrations

This commit is contained in:
Andrew Godwin 2014-08-07 12:13:37 +10:00
parent 8d93b21ec9
commit 5257b85ab8
1 changed files with 19 additions and 0 deletions

View File

@ -207,6 +207,8 @@ class ModelState(object):
options[name] = set(normalize_together(it)) options[name] = set(normalize_together(it))
else: else:
options[name] = model._meta.original_attrs[name] options[name] = model._meta.original_attrs[name]
# Force-convert all options to text_type (#23226)
options = cls.force_text_recursive(options)
# If we're ignoring relationships, remove all field-listing model # If we're ignoring relationships, remove all field-listing model
# options (that option basically just means "make a stub model") # options (that option basically just means "make a stub model")
if exclude_rels: if exclude_rels:
@ -250,6 +252,23 @@ class ModelState(object):
bases, bases,
) )
@classmethod
def force_text_recursive(cls, value):
if isinstance(value, six.string_types):
return six.text_type(value)
elif isinstance(value, list):
return [cls.force_text_recursive(x) for x in value]
elif isinstance(value, tuple):
return tuple(cls.force_text_recursive(x) for x in value)
elif isinstance(value, set):
return set(cls.force_text_recursive(x) for x in value)
elif isinstance(value, dict):
return dict(
(cls.force_text_recursive(k), cls.force_text_recursive(v))
for k, v in value.items()
)
return value
def construct_fields(self): def construct_fields(self):
"Deep-clone the fields using deconstruction" "Deep-clone the fields using deconstruction"
for name, field in self.fields: for name, field in self.fields: