1

I have two serializers, one of which is nested:

class PaperSerializer(serializers.ModelSerializer):

    class Meta:
        model = Paper


class AuthorSerializer(serializers.ModelSerializer):
    papers = PaperSerializer(
        many=True,
        read_only=True,
        source='paper_set'
    )

    class Meta:
        model = Author

I want to get a list of Authors which shows only their published Papers (Boolean field exists on the model).

I would like to call the API like /api/v1/authors/?show_published_only=true.

1 Answer 1

3

After some digging around, I discovered that you can pass the context from the ViewSet to the Serializer:

views.py

class AuthorViewSet(viewsets.ModelViewSet):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer
    filter_fields = (
        'show_published_only',
    )

    def get_serializer_context(self):
        return {'request': self.request}

Now, create a new serializer FilteredPaperSerializer which inherits from serializers.ListSerializer, then override the to_representation() method to filter the queryset:

serializers.py

class FilteredPaperSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        # Get the parameter from the URL
        show_published_only = self.context['request'].query_params['show_published_only']

        data = data.filter(is_published=show_published_only)
        return super(FilteredPaperSerializer, self).to_representation(data)

class AuthorSerializer(serializers.ModelSerializer):
    papers = FilteredPaperSerializer(
        many=True,
        read_only=True,
        source='paper_set'
    )

    class Meta:
        model = Author

NB: Don't forget to convert the fetched URL parameter to a Boolean or relevant data type for your model, I neglected to do it in the write-up above.

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.