Home > Software engineering >  Does Django have a way for ModelViewSet to represent both parent and child models?
Does Django have a way for ModelViewSet to represent both parent and child models?

Time:08-19

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>

  • Related