Есть ли в Django способ для ModelViewSet представлять как родительские, так и дочерние модели?
Мне нужно иметь дополнительные поля в ответе если они доступны, но не все объекты этого класса имеют это свойство. Так, например, у нас есть
class Car(models.Model):
brand = model.CharField()
wheelcount = model.IntField()
class Truck(Car):
max_load = model.IntField()
class Bus(Car):
max_people = model.IntField()
и вид
class CarView(ReadOnlyModelViewSet):
serializer_class = CarSerializer
queryset = Car.objects.all()
Есть ли способ либо написать CarSerializer, чтобы он как-то по-другому сериализовал дочерние объекты, либо способ заставить класс представления выбирать сериализатор на основе класса или дополнительного поля (например, иметь enum CarType)?
Вы можете указать, какие поля вы хотите сериализовать обычно в мета-классе.
ex:
class CarSerializer(serializers.ModelSerializer):
class Meta:
model = Car
fields = [<whatever specific fields you want to serialize>]
если вам нужно сериализовать объекты на основе определенных условий, вы можете использовать SerializerMethodField
. https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
Из документации django rest:
Это поле только для чтения. Оно получает свое значение путем вызова метода на класса сериализатора, к которому оно присоединено. Оно может быть использовано для добавления любого вида данных в сериализованное представление вашего объекта.
Подпись: SerializerMethodField(method_name=None)
.method_name - Имя метода сериализатора, который будет вызван. Если оно не включено, то по умолчанию используется get_<имя_поля>. Сериализатор метод, на который ссылается аргумент method_name, должен принимать единственный аргумент (в дополнение к self), который является сериализуемым объектом. Он должен возвращать все, что вы хотите включить в сериализованное представление объекта. Например:
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
в вашем случае:
class CarSerializer(serializers.ModelSerializer):
object = serializers.SerializerMethodField()
def get_object(self, instance):
if instance.CarType:
return <your desired object>