Home > database >  Django Rest Framework can't add nested obejct
Django Rest Framework can't add nested obejct

Time:05-21

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?

CodePudding user response:

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