You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django REST请求中以二进制数据形式发送图片

解决Django REST框架上传图片(二进制数据)的问题

你的问题核心在于上传文件不能用JSON格式请求,必须用multipart/form-data类型的表单请求发送二进制文件数据,同时你的视图配置未支持文件解析。以下是具体修复步骤:

1. 修正视图的解析器配置

你的NewPost视图仅设置了JSONParser,无法解析文件上传请求,需添加支持文件的解析器:

from rest_framework.parsers import JSONParser, MultiPartParser, FormParser

class NewPost(APIView):
    permission_classes = [IsAuthenticated]
    # 添加MultiPartParser和FormParser以支持文件上传
    parser_classes = [JSONParser, MultiPartParser, FormParser]

    def post(self, request):
        text = request.data.get("text")
        post = Post.objects.create(author=request.user, text=text)
        # 从request.FILES获取上传的文件列表
        images = request.FILES.getlist('images')
        for image in images:
            Images.objects.create(image=image, post_id=post)
        # 用序列化器返回规范响应
        serializer = PostSerializer(post, context={'request': request})
        return Response({
            "message": "Успешно",
            'post': serializer.data
        }, status=status.HTTP_201_CREATED)

2. 正确构造上传请求

不能再使用Content-Type: application/json,需改用multipart/form-data,将文本和二进制文件作为表单字段发送。用VS Code的REST Client编写请求示例如下:

POST {{baseUrl}}/newpost/
Authorization: Token 195c9587649b81fb9a19eeb19024f63d98790f27
Content-Type: multipart/form-data

text="a new post"
images=@small_django_logo.png
images=@small_django_logo.png
  • 用@符号指定本地文件路径,框架会自动将文件转为二进制数据上传
  • 多个同名images字段会被getlist('images')捕获为列表

3. 优化序列化器(可选但推荐)

当前PostSerializer的images字段为只读,手动在视图创建Images实例虽可行,但让序列化器处理关联创建更符合DRF规范:

class PostSerializer(serializers.ModelSerializer):
    images = ImageSerializer(many=True, required=False)
    # 其他字段保持不变

    def create(self, validated_data):
        # 提取图片数据
        images_data = validated_data.pop('images', [])
        # 创建Post实例
        post = Post.objects.create(author=self.context["request"].user, **validated_data)
        # 创建关联的Images实例
        for image_data in images_data:
            Images.objects.create(post_id=post, **image_data)
        return post

对应的视图可简化为:

def post(self, request):
    serializer = PostSerializer(data=request.data, context={'request': request})
    if serializer.is_valid():
        serializer.save()
        return Response({
            "message": "Успешно",
            'post': serializer.data
        }, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

4. 验证结果

发送请求后,通过GET请求获取该帖子,images字段会返回图片的访问URL,示例如下:

{
    "id": 34,
    "author": {
        "id": 1,
        "username": "admin"
    },
    "text": "a new post",
    "images": [
        {"image": "/media/images/small_django_logo_xxxx.png"},
        {"image": "/media/images/small_django_logo_yyyy.png"}
    ],
    "created_at": "2025-02-04T15:00:00.000000Z",
    "likes_count": 0,
    "comments": []
}

内容的提问来源于stack exchange,提问作者user29389183

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:15:04