如何更新 django rest 框架中的多个对象?

Posted

技术标签:

【中文标题】如何更新 django rest 框架中的多个对象?【英文标题】:How to update multiple objects in django rest framework? 【发布时间】:2020-06-01 03:29:47 【问题描述】:

我正在尝试使用我在每个需要更新的对象中传递的 ID 更新多个对象,但找不到任何成功的方法。这是我的代码

models.py

class EventTicket(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid_generate_v1mc, editable=False)
    name = models.CharField(max_length=250)
    description = models.TextField(max_length=1000)

views.py

  class EventTicketView(APIView, PaginationHandlerMixin):
        permission_classes = (AllowAny,)
        def get_object(self, ticket_id):
            try:
                return EventTicket.objects.get(id=ticket_id)
            except EventTicket.DoesNotExist():
                raise status.HTTP_400_BAD_REQUEST
        def patch(self, request, *args, **kwargs):
            for each_ticket in request.data:

                ticket_id = self.get_object(each_ticket['ticket_id'])

                serializer = EventTicketSerializer(instance=ticket_id,data=request.data,partial=True)
                if serializer.is_valid():
                    serializer.save()
                    result = 
                        'message': "updated sucessfully"
                    
                    return Response(result, status=status.HTTP_201_CREATED)
                else:
                    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

序列化器.py

class EventTicketSerializer(serializers.ModelSerializer):
    class Meta:
        model = EventTicket
        fields = ['name', 'description']
```

I have to send data like list of multiple objects :::
[
    
    "ticket_id": "054665ea-4fde-11ea-94b2-9f415c43ba4c",    
    "name": "chris",
    "description":"The golden ticket for day only",

    ,
       
    "ticket_id": "054656ea-4fde-11ea-94b2-9f415c43ba4c",
    "name": "daut",
    "description":"The premium ticket for day only",

    
]

【问题讨论】:

那么你得到了什么错误? 错误是 :: "non_field_errors": [ "无效数据。需要字典,但得到了列表。" ] 【参考方案1】:

以下代码将使您正确理解在单个请求中更新多个对象。 要在单个请求中更新多个对象,最好使用 PUT 方法而不是 PATCH。 这里给出的身体数据是。

身体数据


    "ids":[
        "5e41770d2e8fa013d1f034ec",
        "5e41772c2e8fa013d1f034ee",
        "5e4177702e8fa013d1f034f2",
        "5e453f302e8fa075aa18b277",
        "5e4a314f2e8fa070c5251a0a"
    ]

对于给定的 DemoConfig 模型 ID,我正在将 enabled 属性从 False 更新为 True。 同样,您可以更新您的数据。根据您的要求,您可以编写validate 方法来验证正文数据。 序列化程序已写入序列化响应的实例数据。

class DemoAPI(APIView):

    def get_object(self, obj_id):
        try:
            return DemoConfig.objects.get(id=obj_id)
        except (DemoConfig.DoesNotExist, ValidationError):
            raise status.HTTP_400_BAD_REQUEST

    def validate_ids(self, id_list):
        for id in id_list:
            try:
                DemoConfig.objects.get(id=id)
            except (DemoConfig.DoesNotExist, ValidationError):
                raise status.HTTP_400_BAD_REQUEST
        return True

    def put(self, request, *args, **kwargs):
        id_list = request.data['ids']
        self.validate_ids(id_list=id_list)
        instances = []
        for id in id_list:
            obj = self.get_object(obj_id=id)
            obj.enabled = True
            obj.save()
            instances.append(obj)
        serializer = DemoSerializer(instances, many=True)
        return Response(serializer.data)

这个视图的序列化器是:

class DemoSerializer(DocumentSerializer):
    class Meta:
        model = DemoConfig
        fields = '__all__'

输出:


  "data": [
    
      "id": "5e41770d2e8fa013d1f034ec",
      "name": "CONFIG_1",
      "enabled": true,

    ,
    
      "id": "5e41772c2e8fa013d1f034ee",
      "name": "CONFIG_2",
      "enabled": true,

    ,
    
      "id": "5e4177702e8fa013d1f034f2",
      "name": "CONFIG_3",
      "enabled": true,

    ,
    
      "id": "5e453f302e8fa075aa18b277",
      "name": "CONFIG_4",
      "enabled": true,

    ,
    
      "id": "5e4a314f2e8fa070c5251a0a",
      "name": "CONFIG_5",
      "enabled": true,

    
  ]

根据您的代码要求,您需要按照以下方式使用 put 方法。

    def put(self, request, *args, **kwargs):
        data = request.data
        ticket_ids = [i['ticket_id'] for i in data]
        self.validate_ids(ticket_ids)
        instances = []
        for temp_dict in data:
            ticket_id = temp_dict['ticket_id']
            name = temp_dict['name']
            description = temp_dict['description']
            obj = self.get_object(ticket_id)
            obj.name = name
            obj.description = description
            obj.save()
            instances.append(obj)
        serializer = DemoSerializer(instances, many=True)
        return Response(serializer.data)

【讨论】:

我发送 BODY DATA 就像一个对象列表,它是 [ "ticket_id": "054665ea-4fde-11ea-94b2-9f415c43ba4c", "name": "chris", "description": "仅限一天的金票", , "ticket_id": "054656ea-4fde-11ea-94b2-9f415c43ba4c", "name": "daut", "description":"仅限一天的高级票", ] 所以使用上面的方法会抛出这个错误::“列表索引必须是整数或切片,而不是 str”。另外我必须在 DATA BODY 中传递名称和描述来更新更新,我们可以做什么修改? 在你的情况下使用``` data = request.data ticket_ids = [i['t​​icket_id'] for i in data] self.validate_ids(ticket_ids) for temp_dict in data: ticket_id = temp_dict[' ticket_id'] name = temp_dict['name'] description = temp_dict['description'] obj = self.get_object(ticket_id) ``` @suresh 根据正文数据检查编辑后的解决方案。 数据验证由您决定……但其标准做法是在更新实例之前验证正文数据。 非常感谢,工作正常,我在验证时犯了一些错误。

以上是关于如何更新 django rest 框架中的多个对象?的主要内容,如果未能解决你的问题,请参考以下文章

在 django rest 框架中删除多个对象

如何在 Django REST 框架中使用事务?

如何使用 rest_framework 和 Django 获取多个对象的响应

尝试覆盖django rest框架中的update方法,以在更新后返回整个查询集

Django REST 框架:使用相关字段创建/更新对象

如何修复 Python(Django Rest 框架模板)中的 UnicodeDecodeError?