Django REST框架发布对象数组

val*_*lov 9 django django-rest-framework restangular

我正在使用Django REST框架用于API和Angular SPA与Restangular用于通信API.有时我必须添加多个对象才能添加,我认为我可以将它们一起发送到数组中并发出一个请求.

当我尝试从Restangular中执行此操作时,我错误地输入了错误输入.如果我尝试从REST框架Web界面添加多个对象,我将传递对象或对象数组:

// this { "text": "gdhg", },{ "text": "gdhg", },{ "text": "gdhg", }
// or this [{ "text": "gdhg", },{ "text": "gdhg", },{ "text": "gdhg", }]
Run Code Online (Sandbox Code Playgroud)

但我收到了ParseError.我错了,我必须改变或如何正确地做.

Tim*_*ayi 13

另一个支持发布数组以及发布单个对象的示例.对于寻找这样一个例子的其他人来说,它可能会有用.

class BookViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    ViewSet create and list books

    Usage single : POST
    {
        "name":"Killing Floor: A Jack Reacher Novel", 
        "author":"Lee Child"
    }

    Usage array : POST
    [{  
        "name":"Mr. Mercedes: A Novel (The Bill Hodges Trilogy)",
        "author":"Stephen King"
    },{
        "name":"Killing Floor: A Jack Reacher Novel", 
        "author":"Lee Child"
    }]
    """
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    search_fields = ('name','author')

    def create(self, request, *args, **kwargs):
        """
        #checks if post request data is an array initializes serializer with many=True
        else executes default CreateModelMixin.create function 
        """
        is_many = isinstance(request.data, list)
        if not is_many:
            return super(BookViewSet, self).create(request, *args, **kwargs)
        else:
            serializer = self.get_serializer(data=request.data, many=True)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Run Code Online (Sandbox Code Playgroud)


vib*_*hor 6

我不确定问题是否仍然存在.但是fiver建议的解决方案并不适用于我.对我有用的是get_serializer仅覆盖该方法.

def get_serializer(self, instance=None, data=None,
                    files=None, many=True, partial=False):
    return super(ViewName, self).get_serializer(instance, data, files,
                                                    many, partial)
Run Code Online (Sandbox Code Playgroud)

如果您注意到我many=True在参数中设置默认值get_serializer.除此之外,不需要任何东西.也不需要重写create方法.

此外,如果您在视图中定义pre_save和post_save方法,则期望列表(iterable)作为方法的参数(当您发布列表时)而不仅仅是单个对象.

def post_save(self, objects, *args, **kwargs):
    """
    In the post_save, list of obj has been created
    """
    for obj in objects:
        do_something_with(obj)
Run Code Online (Sandbox Code Playgroud)


Fiv*_*ver 4

以下是使用 Django REST Framework 在 ListCreateAPIView 中设置批量 POSTing 的示例:

class SomethingList(generics.ListCreateAPIView):
    model = Something
    serializer_class = SomethingSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.DATA, many=True)
        if serializer.is_valid():
            serializer.save()
            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)

这里重要的部分是many=Trueget_serializer()方法的参数。然后,为了让 Angular 更好地发挥作用,您可以将服务工厂定义为:

.factory('Something', ['$resource', function ($resource) {
    return $resource(
        "url_to_something",
        {},
        {
            save: {
                method: 'POST',
                isArray: true
            }
        }
    );
}])
Run Code Online (Sandbox Code Playgroud)

其中重要的部分是isArray: true. 如果您想保留发布单个 JSON 对象,您可以将save上面的内容更改为类似saveBulk或类似的内容。

  • 我用 ModelViewSet 做到了这一点,现在收到“'list'对象没有属性'get'”,因为 request.DATA 是列表。如何解决这个问题。我正在从 api 的 Web 界面测试它,发送 json 对象数组: [{ "text": "gdhg", },{ "text": "gdhg", },{ "text": "gdhg", }] (2认同)