Example #1
0
    def field_to_native(self, obj, field_name):
        try:
            if self.source == '*':
                return self.to_native(obj)

            source = self.source or field_name
            value = obj

            for component in source.split('.'):
                if value is None:
                    break
                value = get_component(value, component)
        except ObjectDoesNotExist:
            return None

        if value is None:
            return None

        if self.many:
            if is_simple_callable(getattr(value, 'all', None)):
                return [self.to_native(item) for item in value.all()]
            else:
                # Also support non-queryset iterables.
                # This allows us to also support plain lists of related items.
                return [self.to_native(item) for item in value]
        return self.to_native(value)
Example #2
0
    def get_attribute(self, instance):
        if self.use_pk_only_optimization() and self.source_attrs:
            # Optimized case, return a mock object only containing the pk attribute.
            try:
                instance = get_attribute(instance, self.source_attrs[:-1])
                value = instance.serializable_value(self.source_attrs[-1])
                if is_simple_callable(value):
                    # Handle edge case where the relationship `source` argument
                    # points to a `get_relationship()` method on the model
                    value = value().pk
                return PKOnlyObject(pk=value)
            except AttributeError:
                pass

        # Standard case, return the object instance.
        return get_attribute(instance, self.source_attrs)
Example #3
0
    def get_attribute(self, instance):
        if self.use_pk_only_optimization() and self.source_attrs:
            # Optimized case, return a mock object only containing the pk attribute.
            try:
                instance = get_attribute(instance, self.source_attrs[:-1])
                value = instance.serializable_value(self.source_attrs[-1])
                if is_simple_callable(value):
                    # Handle edge case where the relationship `source` argument
                    # points to a `get_relationship()` method on the model
                    value = value().pk
                return PKOnlyObject(pk=value)
            except AttributeError:
                pass

        # Standard case, return the object instance.
        return get_attribute(instance, self.source_attrs)
Example #4
0
    def field_to_native(self, obj, field_name):
        if self.many:
            # To-many relationship

            queryset = None
            if not self.source:
                # Prefer obj.serializable_value for performance reasons
                try:
                    queryset = obj.serializable_value(field_name)
                except AttributeError:
                    pass
            if queryset is None:
                # RelatedManager (reverse relationship)
                source = self.source or field_name
                queryset = obj
                for component in source.split('.'):
                    if queryset is None:
                        return []
                    queryset = get_component(queryset, component)

            # Forward relationship
            if is_simple_callable(getattr(queryset, 'all', None)):
                return [self.to_native(item.pk) for item in queryset.all()]
            else:
                # Also support non-queryset iterables.
                # This allows us to also support plain lists of related items.
                return [self.to_native(item.pk) for item in queryset]

        # To-one relationship
        try:
            # Prefer obj.serializable_value for performance reasons
            pk = obj.serializable_value(self.source or field_name)
        except AttributeError:
            # RelatedObject (reverse relationship)
            try:
                pk = getattr(obj, self.source or field_name).pk
            except (ObjectDoesNotExist, AttributeError):
                return None

        # Forward relationship
        return self.to_native(pk)
Example #5
0
    def field_to_native(self, obj, field_name):
        if self.many:
            # To-many relationship

            queryset = None
            if not self.source:
                # Prefer obj.serializable_value for performance reasons
                try:
                    queryset = obj.serializable_value(field_name)
                except AttributeError:
                    pass
            if queryset is None:
                # RelatedManager (reverse relationship)
                source = self.source or field_name
                queryset = obj
                for component in source.split('.'):
                    if queryset is None:
                        return []
                    queryset = get_component(queryset, component)

            # Forward relationship
            if is_simple_callable(getattr(queryset, 'all', None)):
                return [self.to_native(item.pk) for item in queryset.all()]
            else:
                # Also support non-queryset iterables.
                # This allows us to also support plain lists of related items.
                return [self.to_native(item.pk) for item in queryset]

        # To-one relationship
        try:
            # Prefer obj.serializable_value for performance reasons
            pk = obj.serializable_value(self.source or field_name)
        except AttributeError:
            # RelatedObject (reverse relationship)
            try:
                pk = getattr(obj, self.source or field_name).pk
            except (ObjectDoesNotExist, AttributeError):
                return None

        # Forward relationship
        return self.to_native(pk)
Example #6
0
    def get_attribute(self, instance):
        if self.use_pk_only_optimization() and self.source_attrs:
            # Optimized case, return a mock object only containing the pk attribute.
            try:
                attribute_instance = get_attribute(instance, self.source_attrs[:-1])
                value = attribute_instance.serializable_value(self.source_attrs[-1])
                if is_simple_callable(value):
                    # Handle edge case where the relationship `source` argument
                    # points to a `get_relationship()` method on the model.
                    value = value()

                # Handle edge case where relationship `source` argument points
                # to an instance instead of a pk (e.g., a `@property`).
                value = getattr(value, 'pk', value)

                return PKOnlyObject(pk=value)
            except AttributeError:
                pass

        # Standard case, return the object instance.
        return super().get_attribute(instance)
    def field_to_native(self, obj, field_name):
        """
        Override default so that the serializer can be used as a nested field
        across relationships.
        """
        if self.write_only:
            return None

        if self.source == '*':
            return self.to_native(obj)

            # Get the raw field value
        try:
            source = self.source or field_name
            value = obj

            for component in source.split('.'):
                if value is None:
                    break
                value = get_component(value, component)
        except ObjectDoesNotExist:
            return None

        if is_simple_callable(getattr(value, 'all', None)):
            filtered_queryset = value.filter(self.get_related_filter())
            return [self.to_native(item) for item in filtered_queryset]

        if value is None:
            return None

        if self.many is not None:
            many = self.many
        else:
            many = hasattr(value, '__iter__') and not isinstance(value, (Page, dict, six.text_type))

        if many:
            return [self.to_native(item) for item in value]
        return self.to_native(value)
 def to_representation(self, model: Model):
     value = getattr(model, self.custom_field_name)
     if is_simple_callable(value):
         return value()
     return value