Package: django-rest-polymorphic
Django REST PolymorphicPolymorphic serializers for Django REST Framework.Overviewdjango-rest-polymorphicallows you to easily define serializers for your inherited models that you have created usingdjango-polymorphiclibrary.InstallationInstall usingpip:$pipinstalldjango-rest-polymorphicUsageDefine your polymorphic models:# models.pyfromdjango.dbimportmodelsfrompolymorphic.modelsimportPolymorphicModelclassProject(PolymorphicModel):topic=models.CharField(max_length=30)classArtProject(Project):artist=models.CharField(max_length=30)classResearchProject(Project):supervisor=models.CharField(max_length=30)Define serializers for each polymorphic model the way you did it when you useddjango-rest-framework:# serializers.pyfromrest_frameworkimportserializersfrom.modelsimportProject,ArtProject,ResearchProjectclassProjectSerializer(serializers.ModelSerializer):classMeta:model=Projectfields=('topic',)classArtProjectSerializer(serializers.HyperlinkedModelSerializer):classMeta:model=ArtProjectfields=('topic','artist','url')extra_kwargs={'url':{'view_name':'project-detail','lookup_field':'pk'},}classResearchProjectSerializer(serializers.ModelSerializer):classMeta:model=ResearchProjectfields=('topic','supervisor')Note that if you extendHyperlinkedModelSerializerinstead ofModelSerializeryou need to defineextra_kwargsto direct the URL to the appropriate view for your polymorphic serializer.Then you have to create a polymorphic serializer that serves as a mapper between models and serializers which you have defined above:# serializers.pyfromrest_polymorphic.serializersimportPolymorphicSerializerclassProjectPolymorphicSerializer(PolymorphicSerializer):model_serializer_mapping={Project:ProjectSerializer,ArtProject:ArtProjectSerializer,ResearchProject:ResearchProjectSerializer}Create viewset with serializer_class equals to your polymorphic serializer:# views.pyfromrest_frameworkimportviewsetsfrom.modelsimportProjectfrom.serializersimportProjectPolymorphicSerializerclassProjectViewSet(viewsets.ModelViewSet):queryset=Project.objects.all()serializer_class=ProjectPolymorphicSerializerTest it:$httpGET"http://localhost:8000/projects/"HTTP/1.0200OKContent-Length:227Content-Type:application/json[{"resourcetype":"Project","topic":"John's gathering"},{"artist":"T. Turner","resourcetype":"ArtProject","topic":"Sculpting with Tim","url":"http://localhost:8000/projects/2/"},{"resourcetype":"ResearchProject","supervisor":"Dr. Winter","topic":"Swallow Aerodynamics"}]$httpPOST"http://localhost:8000/projects/"resourcetype="ArtProject"topic="Guernica"artist="Picasso"HTTP/1.0201CreatedContent-Length:67Content-Type:application/json{"artist":"Picasso","resourcetype":"ArtProject","topic":"Guernica","url":"http://localhost:8000/projects/4/"}Customize resource typeAs you can see from the example above, in order to specify the type of your polymorphic model, you need to send a request with resource type field. The value of resource type should be the name of the model.If you want to change the resource type field name fromresourcetypeto something else, you should overrideresource_type_field_nameattribute:classProjectPolymorphicSerializer(PolymorphicSerializer):resource_type_field_name='projecttype'...If you want to change the behavior of resource type, you should overrideto_resource_typemethod:classProjectPolymorphicSerializer(PolymorphicSerializer):...defto_resource_type(self,model_or_instance):returnmodel_or_instance._meta.object_name.lower()Now, the request for creating new object will look like this:$httpPOST"http://localhost:8000/projects/"projecttype="artproject"topic="Guernica"artist="Picasso"