使用Fetch向Django视图提交表单时无法获取POST数据的问题
问题描述
我是Django和Fetch API新手,尝试结合两者开发。参考相关资料后,用Fetch向Django视图POST表单数据,但视图无法检测到POST数据,request.POST和request.body都为空,返回的是初始模型对象的JSON响应。
HTML表单代码
<form class="basicform"> <label for="nametextbox">Change First Name</label> <input type="text" name="nametextbox"> </form>
Fetch POST请求代码
function postForm(id, form){ var formData = new FormData (form); let response = fetch("{% url 'fetch-ppl' '12345' %}".replace('12345',id), { method: 'POST', body: formData, headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json', "X-CSRFToken": getCookie("csrftoken") }, }) .then(response => response.json()) .then(data=>{ console.log(data); }) return 'Post Done'; }
Django视图代码
def post_form_rest(request, pk): ppl = PersonalData.objects.get(id=pk) serializer = PersonalDataSerializer(ppl,many=False) if (request.method == 'POST'): print("It's a Post Request") print(request.POST); print("Contents of Body") print(request.body); data = ["post request done"] return JsonResponse(data, safe=False) print("it wasn't a post request") return JsonResponse(serializer.data)
日志输出
2023-08-25 20:52:14 It's a Post Request 2023-08-25 20:52:14 2023-08-25 20:52:14 <QueryDict: {}> 2023-08-25 20:52:14 2023-08-25 20:52:14 Contents of Body 2023-08-25 20:52:14 2023-08-25 20:52:14 b'------WebKitFormBoundary3j9PtnVhAWSkfB14--\r\n' 2023-08-25 20:52:14
问题原因及解决办法
核心问题:请求头Content-Type设置错误
当使用FormData作为请求body时,浏览器会自动生成包含边界字符串的multipart/form-data请求头。但手动设置Content-Type: application/json后,Django无法正确解析请求体,导致request.POST为空。
修复步骤:
移除手动设置的
Content-Type
修改Fetch请求的headers,删掉'Content-Type': 'application/json',让浏览器自动处理:function postForm(id, form){ var formData = new FormData (form); let response = fetch("{% url 'fetch-ppl' '12345' %}".replace('12345',id), { method: 'POST', body: formData, headers: { 'Accept': 'application/json, text/plain, */*', "X-CSRFToken": getCookie("csrftoken") }, }) .then(response => response.json()) .then(data=>{ console.log(data); }) return 'Post Done'; }在Django视图中正确获取数据
修复后request.POST即可正常读取表单数据,比如获取输入框内容:def post_form_rest(request, pk): ppl = PersonalData.objects.get(id=pk) serializer = PersonalDataSerializer(ppl,many=False) if request.method == 'POST': print("It's a Post Request") print(request.POST.get('nametextbox')) # 可获取输入内容 print("Contents of Body") print(request.body) data = ["post request done"] return JsonResponse(data, safe=False) print("it wasn't a post request") return JsonResponse(serializer.data)
额外注意:
- 确保表单输入控件带有
name属性(代码中已设置name="nametextbox",无需修改) - CSRF令牌的获取和设置逻辑正确,无需调整
内容的提问来源于stack exchange,提问作者arsarc
相关产品推荐
相关产品推荐

