1

I feel like this is probably in the docs but I just can't seem to figure it out.

If I've got a serializer with a ForeignKey included in its fields how do I exclude that FK when that serializer is nested in the related object?

class EmployerSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Employer
        fields = ('name', 'person')

class PersonSerializer(serializers.HyperlinkedModelSerializer):
    employers = EmployerSerializer()

    class Meta:
        model = Person
        fields = ('name', 'employers')
        depth = 1

When I hit the API at http://0.0.0.0:8000/person/1/ it lists something like:

{
    "name": "Joe Blow",
    "employers": {
        "name": "Acme Inc."
        "person": "http://0.0.0.0:8000/person/1/"
        }
}

The "person" key for "employers" is self-referential and redundant, but only when the serializer is nested within the object it's referring to.

It seems like there should be an option to exclude it when the serializer is nested, but I can't figure it out.

1 Answer 1

7
class DynamicFieldsModelSerializer(serializers.HyperlinkedModelSerializer):
    """
    A HyperlinkedModelSerializer that takes an additional `fields` argument that
    controls which fields should be displayed.
    """

    def __init__(self, *args, **kwargs):
        # Don't pass the 'fields' arg up to the superclass
        fields = kwargs.pop('fields', None)
        exclude = kwargs.pop('exclude', None)
        # Instantiate the superclass normally
        super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)

        if fields:
            # Drop any fields that are not specified in the `fields` argument.
            allowed = set(fields)
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)
        if exclude:
            # Drop fields that are specified in the `exclude` argument.
            excluded = set(exclude)
            for field_name in excluded:
                try:
                    self.fields.pop(field_name)
                except KeyError:
                    pass

extend EmployerSerializer with DynamicFieldsModelSerializer

class EmployerSerializer(DynamicFieldsModelSerializer):
    class Meta:
       model = Employer
       fields = ('name', 'person')


class PersonSerializer(serializers.HyperlinkedModelSerializer):
    employers = EmployerSerializer(exclude=('name',))
    class Meta:
        model = Person
        fields = ('name', 'employers')
        depth = 1
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.