Django Rest Framework can't add nested obejct

Viewed 42

I'm quite new in drf and I'm trying to display nested objects and have the choices functionality in the ListCreateView at the same time

models.py

class CarBrand(SoftDeletionModel):
    CAR_BRAND_NAME_MAX_LEN = 30
    name = models.CharField(
        max_length=CAR_BRAND_NAME_MAX_LEN,
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
    )

    def __str__(self):
        return self.name

class CarModel(SoftDeletionModel):
    CAR_MODEL_NAME_MAX_LEN = 30
    name = models.CharField(
        max_length=CAR_MODEL_NAME_MAX_LEN,
    )
    car_brand = models.ForeignKey(
       CarBrand,
       on_delete=models.CASCADE,
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
    )
    updated_at = models.DateTimeField(
        auto_now=True,
    )

My logic is to have car brands and then when creating a new car model to specify existing car brand

serializers.py

class FullCarBrandSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarBrand
        fields = ('id', 'name', 'created_at')


class IdAndNameCarBrandSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarBrand
        fields = ('id', 'name')


class FullCarModelSerializer(serializers.ModelSerializer):
    car_brand = IdAndNameCarBrandSerializer(many=False)

    class Meta:
        model = CarModel
        fields = ('id', 'name', 'created_at', 'updated_at', 'car_brand')

When I don't have car_brand = IdAndNameCarBrandSerializer(many=False) the creating part with the choices of the car brands works correctly correct_choices_img, but that's not the way I want to display the JSON incorrect_nested_field_img(it shows only the id, but I want id and name) however when I add that same line again I get what I want in the JSON which is like this correct_nested_field_img, but the functionality of choosing exciting car brands goes away incorrect_choices_img I think it wants me to create a new brand with it, but that's not I want

views.py

class CarModelListCreateView(api_views.ListCreateAPIView):
     queryset = CarModel.objects.all()
     serializer_class = FullCarModelSerializer

Question What is the right way of displaying the nested objects and have the create functionality with the choices?

1 Answers

I'm not really good in django, but I'm trying to answer this question.

To do this, you simply have to :

Add one class to your serializers.py

serializers.py

...

class FullCarModelSerializer(serializers.ModelSerializer):
    car_brand = IdAndNameCarBrandSerializer(many=False)

    class Meta:
        model = CarModel
        fields = ('id', 'name', 'created_at', 'updated_at', 'car_brand')

class CreateCarModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = CarModel
        fields = ('id', 'name', 'car_brand')

Add one method to existing views class.

views.py

class CarModelListCreateView(api_views.ListCreateAPIView):
     queryset = CarModel.objects.all()
     serializer_class = FullCarModelSerializer

    def get_serializer_class(self):
        if self.request.method == 'POST':
            return CreateCarModelSerializer
        return FullCarModelSerializer

You can refer to api guides from Django rest framework.

serializer_class - The serializer class that should be used for validating and deserializing input, and for serializing output. Typically, you must either set this attribute, or override the get_serializer_class() method.

Related