Django restframework无法使用多部分解析器获取post数据

ozxc1zmp  于 2023-02-06  发布在  Go
关注(0)|答案(2)|浏览(130)

我尝试使用django restframework保存带有图像的对象,但当我使用FormParser和MultiPartParser类时,request.data对象似乎收到编码的消息,当我尝试使用utf-8解码时,它输出错误,说明此数据不是utf-8
我希望能够访问request.data数据并能够保存图像以备将来请求
下面是我视图函数:

@parser_classes([FormParser, MultiPartParser])
@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def products(request):
    if request.method == 'POST':
        print(request.data)

        serializer = ProductSerializer(data=request.data)
        
        serializer.initial_data['user'] = request.user.pk

        serializer.initial_data['price'] = float(
            request.data['price'])

        serializer.initial_data['quantity'] = int(
            request.data['quantity'])

        if serializer.is_valid():
            serializer.save()
            return Response({'message': "product added"}, status=status.HTTP_201_CREATED)
        else:
            print(serializer.errors)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我的前端代码:

export const addProduct = async (product) => {
    const fd = new FormData();
    fd.append("name", product.name);
    fd.append("price", product.price);
    fd.append("quantity", product.quantity);
    fd.append("image_url", product.image_url);

    console.log(product.image_url) //this prints a file object

    const response = await fetch(`${URL}/products`, {
        method: "POST",
        headers: {
            "Content-Type": `multipart/form-data; boundary=${fd._boundary}`,
        },
        body: fd,
    })
    return response
}
nmpmafwu

nmpmafwu1#

图像数据没有被编码为UTF-8(也许!如果是这样的话),您可以在序列化器中使用FileField或ImageField字段,沿着FormParser和MultiPartParser类!
[更新]您的观点应该是:

@parser_classes([FormParser, MultiPartParser])
@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def products(request):
    if request.method == 'POST':
        serializer = ProductSerializer(data=request.data)
        serializer.initial_data['user'] = request.user.pk

        if 'price' in request.data:
            serializer.initial_data['price'] = float(request.data['price'])
        else:
            return Response({'error': 'price not found in request data'}, status=status.HTTP_400_BAD_REQUEST)

        if 'quantity' in request.data:
            serializer.initial_data['quantity'] = int(request.data['quantity'])
        else:
            return Response({'error': 'quantity not found in request data'}, status=status.HTTP_400_BAD_REQUEST)

        if serializer.is_valid():
            serializer.save()
            return Response({'message': "product added"}, status=status.HTTP_201_CREATED)
        else:
            print(serializer.errors)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

串行化器:

class ProductSerializer(serializers.ModelSerializer):
    image_url = serializers.ImageField()
    
    class Meta:
        model = Product
        fields = ['name', 'price', 'quantity', 'image_url', 'user']
bvuwiixz

bvuwiixz2#

所以当我删除头文件时,它工作得很好,所以很明显,如果你选择使用multipart/form-data,那么服务器最终接收到的文件数据中一定不能出现边界。
multipart/form-data的问题在于文件数据中不能存在边界分隔符(参见RFC 2388;第5.2节还包括一个相当蹩脚的借口,没有一个适当的聚合MIME类型来避免这个问题)。
所以我通过删除前端的边界来修复它,这使得我的前端代码看起来像这样

const fd = new FormData();
fd.append("name", product.name);
fd.append("price", product.price);
fd.append("quantity", product.quantity);
fd.append("image_url", product.image_url);

console.log(product.image_url) // this print a File object

const response = await fetch(`${URL}/products`, {
    method: "POST",
    headers: {
        Authorization: `token ${localStorage.getItem("auth")}`
    },
    body: fd,
})

相关问题