如果前端依赖 Django 模板 + form,耦合高、异常处理也不方便。
更稳的方式是:前端用 FormData + Ajax 上传,后端仅接收文件,返回 JSON。
前端代码
file_upload.html
<form id="id_ajax_upload_form" class="ui form" method="post" onkeypress="return event.keyCode !== 13;">
<div class="field">
<label>User IDs:</label>
<input type="file" id="user_ids" name="user_ids" />
</div>
{% csrf_token %}
<button class="upload ui teal button">Upload</button>
</form>
Ajax 请求
$(".upload").click(function (e) {
const form = $("form")[0];
const formData = new FormData(form);
if (form.checkValidity()) {
e.preventDefault();
$.ajax({
url: "/upload",
type: "POST",
data: formData,
success: function (data) {
if (data.success) {
alert("Success");
} else {
alert("Fail: " + data.errors);
}
},
enctype: "multipart/form-data",
cache: false,
contentType: false,
processData: false,
});
}
});
说明:
contentType: false和processData: false是关键,否则文件会被错误序列化。- 若启用 CSRF,需要确保请求携带 CSRF token(模板里已有
{% csrf_token %})。
后端代码
直接读取 request.FILES
from django.http import JsonResponse
def upload(request):
my_file = request.FILES.get("my_file")
if not my_file:
return JsonResponse({"success": False, "errors": "file required"})
# 处理文件...
return JsonResponse({"success": True})
使用表单验证
forms.py
from django import forms
class MyForm(forms.Form):
my_file = forms.FileField(allow_empty_file=False)
views.py
from django.http import JsonResponse
from django.shortcuts import render
from .forms import MyForm
def upload(request):
if request.method == "POST":
form = MyForm(request.POST, request.FILES)
if form.is_valid():
# form.save() # 如果是 ModelForm
return JsonResponse({"success": True, "message": "Uploaded Successfully"})
return JsonResponse({"success": False, "errors": form.errors})
return render(request, "file_upload.html", {"form": MyForm()})
小结
- 前端用
FormData+ Ajax,后端只管接收和校验。 - 返回 JSON,异常处理更干净。
- 想要更清晰的错误信息,可以在后端统一封装响应结构。