Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set different Serializer for list and detail view with Django Rest Framework?

How do I set a different Serializer for list and detail view while using viewsets.ModelViewSet and HyperlinkedSerializer?

I see how to do it with viewsets.ViewSet by defining list and retrive, (here's an example) but I don't know how to elegantly adapt it to viewsets.ModelViewSet

like image 210
andilabs Avatar asked Jul 17 '14 17:07

andilabs


People also ask

What are different types of serializer in Django REST?

The serializers in REST framework work very similarly to Django's Form and ModelForm classes. The two major serializers that are most popularly used are ModelSerializer and HyperLinkedModelSerialzer.

What is difference between APIView and ViewSet?

APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.

What is QuerySet in Django REST framework?

The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects. The default behavior of REST framework's generic list views is to return the entire queryset for a model manager.

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.


1 Answers

I've adapted an answer from "Django rest framework, use different serializers in the same ModelViewSet" that serves me very well, and I hope you'll find useful:

class MyModelViewSet(viewsets.MyModelViewSet):      queryset = MyModel.objects.all()     serializer_class = MyModelListSerializer     detail_serializer_class = MyModelDetailSerializer      def get_serializer_class(self):         if self.action == 'retrieve':             if hasattr(self, 'detail_serializer_class'):                 return self.detail_serializer_class          return super(MyModelViewSet, self).get_serializer_class() 

In this case, you're just specifying your two serializers and using the one depending on the action. However, this can be made more general (for all actions) as follows:

class MyModelViewSet(viewsets.MyModelViewSet):      queryset = MyModel.objects.all()     serializer_class = MyModelSerializer      action_serializers = {         'retrieve': MyModelDetailSerializer,         'list': MyModelListSerializer,         'create': MyModelCreateSerializer     }      def get_serializer_class(self):          if hasattr(self, 'action_serializers'):             return self.action_serializers.get(self.action, self.serializer_class)          return super(MyModelViewSet, self).get_serializer_class() 
like image 144
bbengfort Avatar answered Oct 04 '22 17:10

bbengfort