【问题标题】:Update multiple objects in django rest在 django rest 中更新多个对象
【发布时间】:2021-10-23 15:44:58
【问题描述】:

我有博客,我会重新排序。当我通过邮递员发送多个对象,然后通过循环更新和保存时出现错误。

这些是我发送的对象 ->

[

    {
            "id":18,
            "name": "a",
            "is_active": true,
            "author_name": 1,
            "category": 1,
            "tag": [1,2],
            "order": 888888
},

{
            "id": 17,
            "name": "a",
            "is_active": true,
            "author_name": 1,
            "category": 1,
            "tag": [
                1
            ],
            "order": 999999999
        }
]

但我有这个错误 -> { “non_field_errors”:[ “无效数据。需要字典,但得到了列表。” ] }

这是我的代码->

serializer.py

class BlogSerializer(serializers.ModelSerializer):

    class Meta:
        model = Blog
        fields = ['id',  'name', 'is_active', 'author_name','category','tag','order']

        extra_kwargs = {
            'is_active': {'read_only': True},
            'id':{"read_only":False}
        }

view.py

class UpdateOrder(generics.UpdateAPIView):
    serializer_class = BlogSerializer
    queryset = Blog.objects.all()


    def put(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, many=isinstance(request.data, list))
        serializer.is_valid(raise_exception=True)
        for i in serializer.validated_data:
            blog = Blog.objects.get(id=i["id"])
            serializer = BlogSerializer(instance=blog, data=request.data)
            serializer.is_valid(raise_exception=True)
            serializer.save()

【问题讨论】:

    标签: python json django rest django-rest-framework


    【解决方案1】:

    generics.UpdateAPIView 一次接受一个元素。因此,为了扩展此行为以支持有效负载列表,您可以使用 APIView 并更新 put 方法,如下例所示:

    from rest_framework.views import APIView, Response
    from . import models, serializers
    
    
    class BlogsAPI(APIView):
        serializer_class = serializers.BlogSerializer
    
        def get_queryset(self):
            return models.Blog.objects.all()
    
        def get(self, request):
            serialized = self.serializer_class(self.get_queryset(), many=True)
            return Response(serialized.data)
    
        def _perform_update(self, elm):
            tags = elm.pop('tag', [])
            pk = models.Blog.objects.update(**elm)
            db_instance = models.Blog.objects.filter(pk=pk).first()
            db_instance.tag.clear()
            db_instance.tag.add(*tags)
    
        def put(self, request):
            data = request.data
            serialized = self.serializer_class(data=data, many=isinstance(data, list))
            serialized.is_valid(raise_exception=True)
            if isinstance(data, list):  # Update multiple elements
                for elm in serialized.validated_data:
                    self._perform_update(elm)
            else:  # Update one element
                self._perform_update(serialized.validated_data)
            return Response({'msg': 'updated'})
    

    【讨论】:

      【解决方案2】:

      这是因为您将 List 作为有效负载传递。将列表更改为字典,即:[] 到 {}

      一些建议(与您面临的错误无关):

      1. 重写序列化程序本身的创建方法。供参考:Stackoverflow
      2. 使用 bulk_create 而不是循环。 Django Documentation

      【讨论】:

        【解决方案3】:

        generics UpdateAPIView 中的 get_serializer 方法创建和 方法如下:

        def get_serializer(self, *args, **kwargs):
                return self.serializer_class(many=True)
        

        并在更新方法中保存(更强大的批量更新)。

        【讨论】:

          猜你喜欢
          • 2021-04-04
          • 2020-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多