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

如何在Django Rest Framework中同时上传文本与文件并解决JSONParser报错

错误根因

当请求中包含文件时,必须使用multipart/form-data格式编码,你代码中使用的JSONParser仅支持解析application/json格式的纯文本请求体,无法识别二进制文件内容,因此直接抛出解析错误。

修复步骤

1. Django后端视图修改

你原有的POST请求逻辑中的解析逻辑完全不适用于文件上传场景,直接替换为以下两种写法任意一种即可:

写法1:使用DRF自带解析器(推荐)

# views.py
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.decorators import parser_classes

@csrf_exempt
@parser_classes([MultiPartParser, FormParser])
def ChapterApi(request, id=0):
    if request.method=='GET':
        chapters=UploadChapter.objects.all()
        chaptersSerializer=UploadChapterSerializer(chapters, many=True)
        return JsonResponse(chaptersSerializer.data, safe=False)
    elif request.method=='POST':
        # 解析器会自动将文本字段、文件合并到request.data中,直接传给序列化器即可
        chaptersSerializer=UploadChapterSerializer(data=request.data)
        if chaptersSerializer.is_valid():
            chaptersSerializer.save()
            return JsonResponse('Added Successfully', safe=False)
        # 新增错误返回,方便排查参数校验问题
        return JsonResponse({'msg':'Failed', 'errors': chaptersSerializer.errors}, status=400)

写法2:手动读取请求数据

如果不想引入DRF的解析器装饰器,也可以手动从请求中提取参数:

# views.py POST逻辑替换
elif request.method=='POST':
    upload_data = {
        "chapter_number": request.POST.get("chapter_number"),
        "chapter_file": request.FILES.get("chapter_file"),
        "student": request.POST.get("student"),
        "supervisor": request.POST.get("supervisor"),
        "status": request.POST.get("status", "Pending")
    }
    chaptersSerializer=UploadChapterSerializer(data=upload_data)
    if chaptersSerializer.is_valid():
        chaptersSerializer.save()
        return JsonResponse('Added Successfully', safe=False)
    return JsonResponse({'msg':'Failed', 'errors': chaptersSerializer.errors}, status=400)

2. Angular前端配置要求

前端请求必须按照以下规则编写,否则后端依然无法解析:

  • 所有参数必须封装到FormData对象中,禁止直接提交JSON对象
  • 不要手动设置Content-Type请求头,浏览器会自动生成带边界标识的multipart/form-data请求头,手动设置会导致边界标识丢失,解析失败

Angular请求示例:

uploadChapter(formValue: any, uploadFile: File) {
  const formData = new FormData();
  // 追加文本参数,key要和后端序列化器字段名一致
  formData.append('chapter_number', formValue.chapter_number);
  formData.append('student', formValue.student_id);
  formData.append('supervisor', formValue.supervisor_id);
  // 追加文件参数,key对应序列化器的chapter_file字段
  formData.append('chapter_file', uploadFile, uploadFile.name);
  
  // 发送请求,不需要手动加Content-Type头
  return this.http.post('/你的接口路径', formData);
}
可选配置(文件存储必备)

需要在Django项目配置中添加媒体文件配置,否则上传的文件无法正常存储和访问:

  1. settings.py新增配置:
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
  1. 项目根urls.py添加静态资源路由(仅开发环境生效):
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 原有其他路由
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

内容的提问来源于stack exchange,提问作者Buhari Ahmed Alhassan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 18:57:01