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:
- /api/order/info - which shows all the order fields
- /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