bananas/models.py
def from_model(cls, model, *fields, **named_fields):
        """
        Work-in-progress constructor,
        consuming fields and values from django model instance.
        """
        d = ModelDict()

        if not (fields or named_fields):
            # Default to all fields
            fields = [f.attname for f in model._meta.concrete_fields]

        not_found = object()

        for name, field in chain(zip(fields, fields), named_fields.items()):
            _fields = field.split("__")
            value = model
            for i, _field in enumerate(_fields, start=1):
                # NOTE: we don't want to rely on hasattr here
                previous_value = value
                value = getattr(previous_value, _field, not_found)

                if value is not_found:
                    if _field in dir(previous_value):
                        raise ValueError(
                            "{!r}.{} had an AttributeError exception".format(
                                previous_value, _field
                            )
                        )
                    else:
                        raise AttributeError(
                            "{!r} does not have {!r} attribute".format(
                                previous_value, _field
                            )
                        )

                elif value is None:
                    if name not in named_fields:
                        name = "__".join(_fields[:i])
                    break

            d[name] = value

        return d
def from_model(cls, model, *fields, **named_fields):
        """
        Work-in-progress constructor,
        consuming fields and values from django model instance.
        """
        d = ModelDict()

        if not (fields or named_fields):
            # Default to all fields
            fields = [f.attname for f in model._meta.concrete_fields]

        not_found = object()

        for name, field in chain(zip(fields, fields), named_fields.items()):
            _fields = field.split("__")
            value = model
            for i, _field in enumerate(_fields, start=1):
                # NOTE: we don't want to rely on hasattr here
                previous_value = value
                value = getattr(previous_value, _field, not_found)

                if value is not_found:
                    if _field in dir(previous_value):
                        raise ValueError(
                            "{!r}.{} had an AttributeError exception".format(
                                previous_value, _field
                            )
                        )
                    else:
                        raise AttributeError(
                            "{!r} does not have {!r} attribute".format(
                                previous_value, _field
                            )
                        )

                elif value is None:
                    if name not in named_fields:
                        name = "__".join(_fields[:i])
                    break

            d[name] = value

        return d
Work-in-progress constructor,
        consuming fields and values from django model instance.