I need to have extra fields in response if they are available, but not all objects of that class have this property. So for example we have
class Car(models.Model):
brand = model.CharField()
wheelcount = model.IntField()
class Truck(Car):
max_load = model.IntField()
class Bus(Car):
max_people = model.IntField()
and a view
class CarView(ReadOnlyModelViewSet):
serializer_class = CarSerializer
queryset = Car.objects.all()
Is there a way to either write CarSerializer to somehow serialize child objects differently, or a way to make view class choose a serializer based on class or additional field(like having an enum CarType)?
CodePudding user response:
You can specify which fields you'd like to serialize normally in the meta class.
ex:
class CarSerializer(serializers.ModelSerializer):
class Meta:
model = Car
fields = [<whatever specific fields you want to serialize>]
if you need to serialize objects based on certain conditions you can use the SerializerMethodField
. https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
From django rest documentation:
This is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object.
Signature: SerializerMethodField(method_name=None)
method_name - The name of the method on the serializer to be called. If not included this defaults to get_<field_name>. The serializer method referred to by the method_name argument should accept a single argument (in addition to self), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
from django.contrib.auth.models import User from django.utils.timezone import now from rest_framework import serializers class UserSerializer(serializers.ModelSerializer): days_since_joined = serializers.SerializerMethodField() class Meta: model = User fields = '__all__' def get_days_since_joined(self, obj): return (now() - obj.date_joined).days
in your case:
class CarSerializer(serializers.ModelSerializer):
object = serializers.SerializerMethodField()
def get_object(self, instance):
if instance.CarType:
return <your desired object>