Как добавить или удалить объекты во вложенных сериализаторах Django с помощью функции update

У меня есть 2 модели - модуль и комната. Модуль может иметь ноль или несколько комнат, а комната может быть добавлена в несколько модулей. Таким образом, между ними существует простое отношение "многие-ко-многим".

При обновлении поля modules с помощью запроса put, Я не хочу обновлять какие-либо комнаты в нем, я просто хочу добавить/удалить комнаты в модуле. Вот мои файлы -

module/models.py -

class Module(models.Model):
    module_id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=100)
    desc = models.TextField()
    rooms = models.ManyToManyField(Rooms)

rooms/models.py -

class Rooms(models.Model):
    room_id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=100)
    desc = models.TextField()
    level = models.CharField(max_length=100)
    is_deleted = models.BooleanField(default=False)

module/serializers.py -

class ModuleSerializer(serializers.ModelSerializer):
    rooms = RoomSerializer(read_only=True, many=True)
    class Meta:
        model = Module
        fields = "__all__"

    def create(self, validated_data):
        rooms_data = validated_data.pop('rooms')
        module = Module.objects.create(**validated_data)
        for data in rooms_data:
            room, created = Rooms.objects.get_or_create(**data)
            module.rooms.add(room)
        return module

rooms/serialier.py -

class RoomSerializerWrite(serializers.ModelSerializer):
    room_id = serializers.IntegerField()
    class Meta:
        model = Rooms
        fields = "__all__"

module/views.py -

class add_module(APIView):
    def post(self, request, format=None):
        module_serializer = ModuleSerializer(data=request.data)
        if module_serializer.is_valid():
            module_serializer.save()
            return Response(module_serializer.data['module_id'], status = status.HTTP_201_CREATED)
        return Response(module_serializer.errors, status = status.HTTP_400_BAD_REQUEST)

Тело запроса POST для обновления модуля в POSTMAN -

{
    "module_id": 2,
    "rooms": [
        {
            "room_id": 2,
            "title": "4",
            "desc": "22",
            "level": "2",
        }
    ],
    "title": "4",
    "desc": "22",
}

Может ли кто-нибудь помочь мне с функцией обновления в модуле/сериализаторе?

Как я понял, вы не хотите обновлять комнаты вашего модуля телом вашего сообщения, на самом деле вы хотите заменить их. Поэтому просто очистите все комнаты из m2m отношений и добавьте новые комнаты из запроса. Что-то вроде;

def update(self, instance, validated_data):
    # get new rooms
    rooms_data = validated_data.get('rooms')
    
    # clear m2m relationship
    instance.rooms_set.clear()
    
    # I assume your rooms_data is a list that contains dicts with room fields
    for room_data in rooms_data:
        # get room instance
        room, created = Rooms.objects.get_or_create(**room_data)
        
        # Add it to m2m relationship
        instance.rooms.add(room)
    instance.save()
    return instance
    

Так что если вы не отправите существующую комнату в ваш сериализатор, она будет удалена из m2m отношений на экземпляре.

Вернуться на верх