[py3] Fixed 'iterable but non string' detection
In Python 3, the str type has an __iter__ attribute. Therefore, the presence of an __iter__ attribute is not sufficient to distinguish 'standard' iterables (list, tuple) from strings.
This commit is contained in:
parent
0955d16a16
commit
db729266d6
|
@ -94,7 +94,7 @@ class Fieldset(object):
|
||||||
class Fieldline(object):
|
class Fieldline(object):
|
||||||
def __init__(self, form, field, readonly_fields=None, model_admin=None):
|
def __init__(self, form, field, readonly_fields=None, model_admin=None):
|
||||||
self.form = form # A django.forms.Form instance
|
self.form = form # A django.forms.Form instance
|
||||||
if not hasattr(field, "__iter__"):
|
if not hasattr(field, "__iter__") or isinstance(field, six.text_type):
|
||||||
self.fields = [field]
|
self.fields = [field]
|
||||||
else:
|
else:
|
||||||
self.fields = field
|
self.fields = field
|
||||||
|
|
|
@ -98,7 +98,7 @@ def Deserializer(object_list, **options):
|
||||||
if field.rel and isinstance(field.rel, models.ManyToManyRel):
|
if field.rel and isinstance(field.rel, models.ManyToManyRel):
|
||||||
if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
|
if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
|
||||||
def m2m_convert(value):
|
def m2m_convert(value):
|
||||||
if hasattr(value, '__iter__'):
|
if hasattr(value, '__iter__') and not isinstance(value, six.text_type):
|
||||||
return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk
|
return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk
|
||||||
else:
|
else:
|
||||||
return smart_text(field.rel.to._meta.pk.to_python(value))
|
return smart_text(field.rel.to._meta.pk.to_python(value))
|
||||||
|
@ -110,7 +110,7 @@ def Deserializer(object_list, **options):
|
||||||
elif field.rel and isinstance(field.rel, models.ManyToOneRel):
|
elif field.rel and isinstance(field.rel, models.ManyToOneRel):
|
||||||
if field_value is not None:
|
if field_value is not None:
|
||||||
if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
|
if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
|
||||||
if hasattr(field_value, '__iter__'):
|
if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type):
|
||||||
obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value)
|
obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value)
|
||||||
value = getattr(obj, field.rel.field_name)
|
value = getattr(obj, field.rel.field_name)
|
||||||
# If this is a natural foreign key to an object that
|
# If this is a natural foreign key to an object that
|
||||||
|
|
|
@ -1035,6 +1035,6 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def prepare_value(self, value):
|
def prepare_value(self, value):
|
||||||
if hasattr(value, '__iter__'):
|
if hasattr(value, '__iter__') and not isinstance(value, six.text_type):
|
||||||
return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value]
|
return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value]
|
||||||
return super(ModelMultipleChoiceField, self).prepare_value(value)
|
return super(ModelMultipleChoiceField, self).prepare_value(value)
|
||||||
|
|
|
@ -656,7 +656,7 @@ class HttpResponse(object):
|
||||||
return b''.join([smart_bytes(e, self._charset) for e in self._container])
|
return b''.join([smart_bytes(e, self._charset) for e in self._container])
|
||||||
|
|
||||||
def _set_content(self, value):
|
def _set_content(self, value):
|
||||||
if hasattr(value, '__iter__'):
|
if hasattr(value, '__iter__') and not isinstance(value, (bytes, six.text_type)):
|
||||||
self._container = value
|
self._container = value
|
||||||
self._base_content_is_iter = True
|
self._base_content_is_iter = True
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue