Django中如何解析request.body中的Multipart文件并正常保存
解决Java WebClient上传Multipart文件到Django时request.POST/FILES为空的问题
问题原因
- Django的
APIView默认不会自动解析multipart/form-data类型请求,导致文件数据滞留在request.body中,无法映射到request.POST和request.FILES。 - 直接保存
request.body会包含multipart请求的边界分隔符、Content-Disposition等头部元数据,并非纯文件内容,因此文件会损坏。
解决方案
步骤1:配置Django APIView的请求解析器
给UpdateJiraAppLogo类添加解析器配置,让Django自动解析multipart请求,将文件存入request.FILES:
from rest_framework.parsers import MultiPartParser, FormParser from rest_framework.views import APIView from rest_framework import status from rest_framework.response import Response from django.utils import timezone class UpdateJiraAppLogo(APIView): # 指定解析multipart请求的解析器 parser_classes = (MultiPartParser, FormParser) def post(self, request, *args, **kwargs): print('POST', request.POST) print('FILES', request.FILES) # 从FILES中获取上传的文件 if 'file' in request.FILES: uploaded_file = request.FILES['file'] now = timezone.now() logo_name = f"logo_{now.strftime('%d_%m_%Y_%H%M%S')}.png" try: with open(f"media/logos/{logo_name}", "wb+") as f: # 分块写入,避免大文件占用过多内存 for chunk in uploaded_file.chunks(): f.write(chunk) # with语句会自动关闭文件,无需手动调用close() except Exception as e: print(e) return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({"status": "success"})
步骤2:优化Java端上传代码(可选,提升兼容性)
显式指定文件名和媒体类型,避免Django解析时出现异常:
public void updateLogo(String clientKey, MultipartFile file) { MultipartBodyBuilder builder = new MultipartBodyBuilder(); // 明确指定文件名和文件类型 builder.part("file", file.getResource()) .filename(file.getOriginalFilename()) .contentType(MediaType.IMAGE_PNG); // 根据实际文件类型调整 Settings prevData = repo.findFirstByClientKey(clientKey); WebClient webClient = WebClient.builder().baseUrl("http://localhost/") .defaultHeader(HttpHeaders.AUTHORIZATION, String.format("Token %s", userToken)).build(); Mono<SettingsLogo> resObj = webClient.post().uri("api/upload-logo") .contentType(MediaType.MULTIPART_FORM_DATA) .body(BodyInserters.fromMultipartData(builder.build())) .retrieve().bodyToMono(SettingsLogo.class) .onErrorResume(WebClientResponseException.class, ex -> { logger.error("Exception", ex); return Mono.empty(); }); }
关键说明
MultiPartParser负责解析multipart/form-data请求,提取文件数据到request.FILES;FormParser处理表单字段到request.POST。- 使用
uploaded_file.chunks()分块写入文件,更适合大文件场景,避免内存溢出。 - 绝对不能直接操作
request.body保存文件,因为其中包含multipart请求的元数据,并非纯净的文件内容。
内容的提问来源于stack exchange,提问作者Shiv
相关产品推荐
相关产品推荐

