fields.py 1.46 KB
Newer Older
1
"""Fields useful for edX API implementations."""
2
from rest_framework.serializers import Field
3 4 5


class ExpandableField(Field):
6 7 8 9 10 11
    """Field that can dynamically use a more detailed serializer based on a user-provided "expand" parameter.

    Kwargs:
      collapsed_serializer (Serializer): the serializer to use for a non-expanded representation.
      expanded_serializer (Serializer): the serializer to use for an expanded representation.
    """
12 13 14 15 16 17 18
    def __init__(self, **kwargs):
        """Sets up the ExpandableField with the collapsed and expanded versions of the serializer."""
        assert 'collapsed_serializer' in kwargs and 'expanded_serializer' in kwargs
        self.collapsed = kwargs.pop('collapsed_serializer')
        self.expanded = kwargs.pop('expanded_serializer')
        super(ExpandableField, self).__init__(**kwargs)

19 20 21 22 23 24
    def to_representation(self, obj):
        """
        Return a representation of the field that is either expanded or collapsed.
        """
        should_expand = self.field_name in self.context.get("expand", [])
        field = self.expanded if should_expand else self.collapsed
25

26 27 28 29
        # Avoid double-binding the field, otherwise we'll get
        # an error about the source kwarg being redundant.
        if field.source is None:
            field.bind(self.field_name, self)
30

31
            if should_expand:
32
                self.expanded.context["expand"] = set(field.context.get("expand", []))
33

34
        return field.to_representation(obj)