Skip to content

Instantly share code, notes, and snippets.

@specialunderwear
Created July 29, 2015 08:37
Show Gist options
  • Save specialunderwear/66a0a436073d7d9b9194 to your computer and use it in GitHub Desktop.
Save specialunderwear/66a0a436073d7d9b9194 to your computer and use it in GitHub Desktop.
Polymorphic serializer
from rest_framework import serializers
from rest_framework.utils.serializer_helpers import BindingDict
class PolymorphicModelSerializer(serializers.ModelSerializer):
"""
Serializer that serializes a polymorphic model
Since the whole point of polymorphism is to have models
with different properties in the same queryset, the ``fields`` meta
specification in rest_framework becomes rather useless. That is
why a new meta specification called ``excluded_fields`` is added,
which should be more useful.
Usage:
>>> class PolymorphicSomethingSerializer(PolymorphicModelSerializer):
>>> class Meta:
>>> model = Something # the polymorphic base class
>>> excluded_fields = ['polymorphic_ctype']
"""
def __init__(self, *args, **kwargs):
super(PolymorphicModelSerializer, self).__init__(*args, **kwargs)
self.fields_table = {}
self.original_model = self.Meta.model
def to_representation(self, data):
self.Meta.model = type(data) if data else self.original_model
return super(PolymorphicModelSerializer, self).to_representation(data)
@serializers.ModelSerializer.fields.getter
def fields(self):
_fields = self.fields_table.get(self.Meta.model, None)
if _fields is None:
_excluded_fields = getattr(self.Meta, 'excluded_fields')
_fields = BindingDict(self)
for key, value in self.get_fields().items():
if key not in _excluded_fields:
_fields[key] = value
self.fields_table[self.Meta.model] = _fields
return _fields
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment