Commit db729266 authored by Claude Paroz's avatar Claude Paroz
Browse files

[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.
parent 0955d16a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ class Fieldset(object):
class Fieldline(object):
    def __init__(self, form, field, readonly_fields=None, model_admin=None):
        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]
        else:
            self.fields = field
+2 −2
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ def Deserializer(object_list, **options):
            if field.rel and isinstance(field.rel, models.ManyToManyRel):
                if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
                    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
                        else:
                            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):
                if field_value is not None:
                    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)
                            value = getattr(obj, field.rel.field_name)
                            # If this is a natural foreign key to an object that
+1 −1
Original line number Diff line number Diff line
@@ -1035,6 +1035,6 @@ class ModelMultipleChoiceField(ModelChoiceField):
        return qs

    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(value)
+1 −1
Original line number Diff line number Diff line
@@ -656,7 +656,7 @@ class HttpResponse(object):
        return b''.join([smart_bytes(e, self._charset) for e in self._container])

    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._base_content_is_iter = True
        else: