
在 django rest framework 中,使用 `request.post.get(“file”)` 无法获取上传的文件,因为文件实际存储在 `request.files` 中,而非 `post`;需通过 `request.files[‘file’]` 访问,并确保视图正确处理 multipart/form-data 请求。
前端使用 FormData.append(“file”, file) 发送文件时,django 并不会将该字段放入 request.POST,而是统一归入 request.FILES —— 这是 Django 对文件上传的标准设计。你当前的代码:
file = request.POST.get("file") # ❌ 总是 None
应改为:
from rest_framework.decorators import api_view from rest_framework.response import Response @api_view(["POST"]) def jobs(request): # ✅ 正确获取 jsON 元数据(字符串) metadata_str = request.POST.get("metadata") if not metadata_str: return Response({"error": "missing metadata"}, status=400) try: import json metadata = json.loads(metadata_str) except json.JSONDecodeError: return Response({"error": "invalid metadata JSON"}, status=400) # ✅ 正确获取上传的文件对象(InMemoryUploadedFile 或 TemporaryUploadedFile) uploaded_file = request.FILES.get("file") if not uploaded_file: return Response({"error": "no file uploaded"}, status=400) print("Metadata:", metadata) print("File name:", uploaded_file.name) # e.g., "image.png" print("File size:", uploaded_file.size) # bytes print("Content type:", uploaded_file.content_type) # e.g., "image/png" # ✅ 示例:安全保存文件(生产环境建议用 django-storages 或异步处理) from django.core.files.base import ContentFile import os from pathlib import Path upload_dir = Path("media/uploads/") upload_dir.mkdir(exist_ok=True) file_path = upload_dir / uploaded_file.name with open(file_path, "wb+") as destination: for chunk in uploaded_file.chunks(): # 防止大文件内存溢出 destination.write(chunk) return Response({ "message": "upload success", "file_url": f"/media/uploads/{uploaded_file.name}" })
⚠️ 关键注意事项:
- 请求头无需手动设置:axios.post(…, formData) 会自动设置 Content-Type: multipart/form-data; boundary=…,切勿手动覆盖(如 headers: {‘Content-Type’: ‘multipart/form-data’}),否则会导致解析失败。
- Django 配置检查:
- 前端可选增强(提升健壮性):
// 添加错误处理与类型校验 formData.append("file", file); if (!file.type.startsWith("image/")) { alert("Please select an image file"); return; }
✅ 总结:文件永远在 request.FILES,不在 request.POST;request.POST 仅包含文本字段(如 metadata 字符串),而二进制文件由 Django 自动解析并封装为 InMemoryUploadedFile 实例,支持 .read(), .chunks(), .name 等标准操作。