Home > Software design >  Django DRF filtering fields in serializer
Django DRF filtering fields in serializer

Time:04-26

I'm new to Django DRF and I'm trying to write a more organized code since the one below lacks the correct approach.

I have 2 API endpoints:

  1. /api/order/info - which shows all the order fields
  2. /api/order/status - which shows only one field

At the moment I have two serializers and two views as follows:

serializers.py

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ['order_id', 'data', 'status']
    
class OrderStatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ['status']



views.py

# /api/order/info - retrieves all fields
class OrderInfo(generics.RetrieveAPIView):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer
    
    def get_object(self):
        try:
            return Order.objects.get(pk=self.request.data['uuid'])
        except Order.DoesNotExist:
            raise Http404
    
# /api/order/status - retrives just one field, the status
class OrderStatus(generics.RetrieveAPIView):
    queryset = Order.objects.all()
    serializer_class = OrderStatusSerializer # a serializer just for this
    
    def get_object(self):
        try:
            return Order.objects.get(pk=self.request.data['uuid'])
        except Order.DoesNotExist:
            raise Http404

The problem: the code works as expected, but it is pretty clear that it is duplicate!

I'm creating a new serializer for just filtering one field, but I strongly believe that DRF makes this easier in some way.

Could you please suggest a better approach? Thanks

CodePudding user response:

Is this solve your problem?

  • Views
class OrderBase(generics.RetrieveAPIView):
    queryset = Order.objects.all()
    
    def get_object(self):
        try:
            return Order.objects.get(pk=self.request.data['uuid'])
        except Order.DoesNotExist:
            raise Http404


class OrderInfo(OrderBase):
    serializer_class = OrderSerializer
    

class OrderStatus(OrderBase):
    serializer_class = OrderStatusSerializer
  • Serializers
class MetaBase:
    model = Order
    fields = '__all__'


class OrderSerializer(serializers.ModelSerializer):
    class Meta(MetaBase):
        fields = ['order_id', 'data', 'status']
    
class OrderStatusSerializer(serializers.ModelSerializer):
    class Meta(MetaBase):
        fields = ['status']

This is called inheritance ;)

CodePudding user response:

You can try using django rest framework to_representation method to send only the fields you need.

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = ['order_id', 'data', 'status']

    def to_representation(self, instance) -> OrderedDict:
        fields = super(OrderSerializer, self).to_representation(instance)
        ret = OrderedDict()
        # your logic to filter out fields based on the request path
        return ret
  • Related