I can't find this info in the docs or on the interwebs.
latest django-rest-framework, django 1.6.5
How does one create a ModelSerializer that can handle a nested serializers where the nested model is implemented using multitable inheritance?
e.g.
######## MODELS
class OtherModel(models.Model):
stuff = models.CharField(max_length=255)
class MyBaseModel(models.Model):
whaddup = models.CharField(max_length=255)
other_model = models.ForeignKey(OtherModel)
class ModelA(MyBaseModel):
attr_a = models.CharField(max_length=255)
class ModelB(MyBaseModel):
attr_b = models.CharField(max_length=255)
####### SERIALIZERS
class MyBaseModelSerializer(serializers.ModelSerializer):
class Meta:
model=MyBaseModel
class OtherModelSerializer(serializer.ModelSerializer):
mybasemodel_set = MyBaseModelSerializer(many=True)
class Meta:
model = OtherModel
This obviously doesn't work but illustrates what i'm trying to do here.
In OtherModelSerializer, I'd like mybasemodel_set to serialize specific represenntations of either ModelA or ModelB depending on what we have.
If it matters, I'm also using django.model_utils and inheritencemanager so i can retrieve a queryset where each instance is already an instance of appropriate subclass.
Thanks
I'm attempting to use a solution that involves different serializer subclasses for the different model subclasses:
That is, when you try and instantiate an object of type
MyBaseModelSerializer
, you actually end up with an object of one of the subclasses, which serialize (and crucially for me, deserialize) correctly.I've just started using this, so it's possible that there are problems I've not run into yet.
I've solved this issue a slightly different way.
Using:
My
models.py
look like this:Basically - The base model is the "Person" model - and a person can either be Clergy, Religious, or neither and simply be a "Person". While the models that inherit
Person
have special relationships as well.In my
views.py
I utilize a mixin to "inject" the subclasses into the queryset like so:And then real "unDRY" part comes in
serializers.py
where I declare the "base" PersonListSerializer, but override theto_representation
method to return special serailzers based on the instance type like so:The "switch" happens in the
to_representation
method of the main serializer (PersonListSerializer
). It looks at the instance type, and then "injects" the needed serializer. SinceClergy
,Religious
are all inherited fromPerson
getting back aPerson
that is also aClergy
member, returns all thePerson
fields and all theClergy
fields. Same goes forReligious
. And if thePerson
is neitherClergy
orReligious
- the base model fields are only returned.Not sure if this is the proper approach - but it seems very flexible, and fits my usecase. Note that I save/update/create
Person
thru different views/serializers - so I don't have to worry about that with this type of setup.I was able to do this by creating a custom relatedfield
I do have concerns that instanting a Serializer for each object is the reverse relation queryset is expensive so I'm wondering if there is a better way to do this.
Another approach i tried was dynamically changing the model field on MyBaseModelSerializer inside of __init__ but I ran into the issue described here:
django rest framework nested modelserializer