Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django rest framework add field when not in list view

I'm using the Django Rest Framework and I'd like to be able to add extra detail to the serializer when a single object is returned, which would be left out of the list view.

In the code below I add the celery_state field to the TestModelSerializer, but I'd only like this field to be added when its returning a single object, not when it's returning the list of TestModel data.

I've looked at the list_serializer_class option but it seems to just use the original model serializer so it will always still include the field even if I try to exclude from there.

What are my options?

class TestModelSerializer(serializers.HyperlinkedModelSerializer):
    celery_state = serializers.CharField(source='celery_state', read_only=True)

    class Meta:
    model = TestModel



class TestModelViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows TestModels to be viewed or edited.
    """
    authentication_classes = (SessionAuthentication, BasicAuthentication)
    permission_classes = (IsAuthenticatedOrReadOnly,)
    queryset = TestModel.objects.all()
    serializer_class = TestModelSerializer
like image 300
joeButler Avatar asked Jan 22 '15 11:01

joeButler


2 Answers

Since the serializer class (used by the viewsets) passes many argument, you can use that to control the fields output:

class TestModelSerializer(serializers.HyperlinkedModelSerializer):
    # ...

    def __init__(self, *args, **kwargs):
        super(TestModelSerializer, self).__init__(*args, **kwargs)
        if kwargs.get('many', False):
            self.fields.pop('celery_state')
like image 200
mariodev Avatar answered Oct 04 '22 03:10

mariodev


Inspired by @mariodev answer:

The other possibility is to override many_init static method in serializer. Acording comments in thie code (https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/serializers.py#L128 ) it is suggested variant.

from rest_framework import serializers

class ExtendedSerializer(serializers.Serializer):
  ...
  @classmethod
  def many_init(cls, *args, **kwargs):
    kwargs['child'] = cls()
    kwargs['child'].fields.pop('extractedFiled')
    return serializers.ListSerializer(*args, **kwargs)
like image 23
Oleg Avatar answered Oct 04 '22 04:10

Oleg