[Django]-Many to Many field and Nested Serializer in REST: Overwriting Nested serializer doesn't create nested object in Django

5👍

You have to explicitly get or create the Building instances, depending upon passed id’s inside the payload data, then add them to BuildingGroup instance.

class NestedBuildingSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)

    class Meta:
        model = Building
        fields = '__all__'


class BuildingGroupSerializer(serializers.ModelSerializer):
    buildings = NestedBuildingSerializer(many=True)

    class Meta:
        model = BuildingGroup
        fields = (
            'description',
            'buildings',
        )

    def create(self, validated_data):
        buildings_data = validated_data.pop('buildings')
        building_group = BuildingGroup.objects.create(**validated_data)
        buildings = []  # it will contains list of Building model instance
        for building_data in buildings_data:
            building_id = building_data.pop('id', None)
            building, _ = Building.objects.get_or_create(id=building_id,
                                                         defaults=building_data)
            buildings.append(building)
        # add all passed instances of Building model to BuildingGroup instance
        building_group.buildings.add(*buildings)
        return building_group

class BuildingGroupView(ListAPIView, CreateAPIView):
    queryset = BuildingGroup.objects.all()
    serializer_class = BuildingGroupSerializer


## Assume you add your views like this in urls.py
urlpatterns = [
    .....
    path('building-groups', views.BuildingGroupView.as_view(),
         name='building-group'),
    .....
]

On calling endpoint /building-groups as POST method with payload like this:

{
  "description": "here description",
  "buildings": [
    {
      "id": 1, # existing building of id 1
      "name": "name of building 1",
      "net_leased_area": 1800
    },
    { 
      # a new building will gets create
      "name": "name of building 2",
      "net_leased_area": 1800
    }
  ]
}

Then , it will return response like this:-

{
  "description": "here description",
  "buildings": [
    {
      "id": 1,
      "name": "name of building 1",
      "net_leased_area": 1800
    },
    {
      "id": 2
      "name": "name of building 2",
      "net_leased_area": 1800
    }
  ]
}

Learn about M2M relationship
and, .get_or_create()

Note: BuildingSerializer and NestedBuildingSerializer are both different. Don’t mix them up.

Leave a comment