form-data not working for ManyToMany field django

hjzp0vay  于 2023-10-21  发布在  Go
关注(0)|答案(3)|浏览(137)

我有2个模型-模块和房间。一个模块可以有零个或多个房间,一个房间可以添加到多个模块中。因此,它们之间存在简单的多对多关系。
在post请求中,原始数据输入可以工作,但表单数据不行。
模块/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, blank=True)
    room_list = models.CharField(max_length = 100, blank=True)

客房/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)

模块/serializers.py-

class ModuleSerializer(serializers.ModelSerializer):
    rooms = RoomSerializerWrite(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 = Rooms.objects.get(**data)
            module.rooms.add(room)
        return module

    def update(self, instance, validated_data):

        # Updating rooms
        rooms_data = validated_data.get('rooms')
        instance.rooms.clear()
        
        for room_data in rooms_data:
            room = Rooms.objects.get(**room_data)
            instance.rooms.add(room)
        
        # Updating other fields
        fields = [
            'title',
            'desc',
            'thumbnail',
            'is_deleted',
        ]
        for field in fields:
            setattr(instance, field, validated_data[field])
        instance.save()
        return instance

客房/serialier.py-

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

模块/views.py-

class add_module(APIView):
def post(self, request, format=None):

    # Adding the rooms to module from room_list
    new_request = request.data.copy()
    room_list=[]
    if 'room_list' in new_request:
        room_list_data = list(new_request['room_list'].split(" "))
        for room in room_list_data:
            room_object = Rooms.objects.get(room_id=room)
            room_serializer = RoomSerializer(room_object)
            room_list.append(room_serializer.data)
    new_request.update({'rooms':room_list})

    # creating the module
    module_serializer = ModuleSerializer(data=new_request)
    if module_serializer.is_valid():
        module_serializer.save()
        return Response(module_serializer.data['module_id'])
    return Response(module_serializer.errors)

更新POSTMAN中模块的POST请求主体-

{
    "module_id": 2,
    "room_list": "1 2",
    "title": "4",
    "desc": "22",
}

请注意,在输入ManyToMany字段-“rooms”时,我将字符串“room_list”作为输入,其中包含要包含的所有room_id。当我在postman中将输入作为raw-data时,这工作得很好,但是当我使用form-data时,它显示-

{
    "rooms": [
        "This field is required."
    ]
}

该怎么办呢?

7tofc5zh

7tofc5zh2#

如果你想在Django中使用FormData将“rooms”解释为数组,你可以做的是传入多个rooms字段,每个字段都有不同的id。Django实际上会将其解释为一个列表,并将其直接并正确地评估为ManyToManyField
因此,如果您想为Model字段传入数据:

rooms = models.ManyToManyField(Rooms, blank=True)

你可以输入数据:

{
    "module_id": 2,
    "rooms": 1,
    "rooms": 2,
    "rooms": 3,
    "rooms": ...,
    "title": "4",
    "desc": "22",
}

完全公开,我只使用JavaScript和FormData对象测试过这个,并通过Axios传递数据。

bq9c1y66

bq9c1y663#

使用这种方法,您可以接受多个字段作为表单数据。将“room_ids”添加到ModuleSerializer。

class ModuleSerializer(serializers.ModelSerializer):
    
    rooms = RoomSerializerWrite(many=True)
    room_ids = serializers.ListField(
        child=serializers.IntegerField(),
        write_only=True,
    )

现在在postman的form-data中,你需要以这种格式传递id列表:
房间_id [0]
房间_id [1] = 2
其中room_ids[0]room_ids[1]是键,1和2是值。

相关问题