1

I'm slowly learning how to work with rest framework and I'm stuck in one part I don't really understand(my english isn't great either). I have this api point: building for which I show some data on api/building/ but I want a certain field to appear only on api/building/1 (1=pk number) and I cannot figure this out how. Here is my serializer code so far:

class FloorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Floor
        fields = ('number',
                  'title')


class BuildingSerializer(serializers.HyperlinkedModelSerializer):
    location = serializers.CharField(source='location_address')
    avg_temperature = serializers.SerializerMethodField('_get_avg_temperature')
    avg_humidity = serializers.SerializerMethodField('_get_avg_humidity')
    occupancy_level = serializers.SerializerMethodField('_get_occupancy_level')
    floors = FloorSerializer(many=True, read_only=True)
    class Meta:
        model = Building
        fields = ('pk',
                  'title',
                  'image_url',
                  'location',
                  'campus_name',
                  'avg_temperature',
                  'avg_humidity',
                  'occupancy_level',
                  'floors')

    def _get_avg_temperature(self, obj):
        # magia filtrului per buildingu asta.
        temp = SensorData.objects.filter(sensor__room__floor__building__pk=obj.pk).filter(sensor__type='TP')\
            .aggregate(Avg('value'))
        return temp

    def _get_avg_humidity(self, obj):
        # magia filtrului per buildingu asta.
        hum = SensorData.objects.filter(sensor__room__floor__building__pk=obj.pk).filter(sensor__type='HU')\
            .aggregate(Avg('value'))
        return hum

    def _get_occupancy_level(self, obj):
        ocup = randint(45, 65)
        return ocup

the field in question is floors. I want to show it only on api/building/pk level and while I read the documentation it is not quite clear to me.

wooshan
  • 15
  • 4

1 Answers1

0

Here is a great answer demonstrating what you should do:

https://stackoverflow.com/a/22755648/2402929

In summary, you should create a serializer that will contain all your methods and fields you want in the list route (/api/building/), then extend that serializer, adding the additional fields you want in the detail routes (/api/building/:pk)

Example:

class BuildingSerializer(serializers.HyperlinkedModelSerializer):

    # additional methods for fields that will be 
    # inherited in the DetailBuildingSerializer

    class Meta:
        model = Building
        fields = ('pk',
                  'title',
                  'image_url',
                  'location',
                  'campus_name',
                  'avg_temperature',
                  'avg_humidity',
                  'occupancy_level',
                  )

class DetailBuildingSerializer(BuildingSerializer):

    class Meta:
        model = Building
        fields = ('pk',
                  'title',
                  'image_url',
                  'location',
                  'campus_name',
                  'avg_temperature',
                  'avg_humidity',
                  'occupancy_level',
                  'floors'
                  )

Later on, separate serializers in your viewset (assuming you are using viewsets):

class BuildingViewset(viewsets.ModelViewSet):
    def get_serializer_class(self):
        if self.action == 'list':
            return serializers.BuildingSerializer
        if self.action == 'retrieve':
            return serializers.BuildingDetailSerializer
Community
  • 1
  • 1
xtrinch
  • 2,232
  • 1
  • 24
  • 46
  • Thank you very much. This explains much. I was reading most of the data provided on http://www.django-rest-framework.org/ but sometimes an explanation with an example like this helps. – wooshan Jun 07 '16 at 15:11