Axios POST请求无法向Django视图传递数据的问题排查
问题:Axios POST请求数据无法被Django视图接收,request.POST返回空QueryDict
服务器返回200状态码,但前端发送的数据未被后端接收,request.POST输出为空的QueryDict:
<QueryDict: {}> [13/Aug/2022 16:44:00] "POST /users/114260670592402026255 HTTP/1.1" 200 9
Django视图代码
from django.shortcuts import render from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt import json from .models import UserProfile @csrf_exempt def get_user_profile(request, user_id): if request.method == 'GET': try: user = UserProfile.objects.get(user_id=user_id) print("user found") except Exception as error: print("User profile wasnt found:") print(error) user = None profile = UserProfile() profile.user_id = user_id profile.searches = [ {'search_term': 'hd'}, {'search_term': 'wba'}, ] profile.save() print("user saved in db") user = UserProfile.objects.get(user_id=user_id) data = { 'user_id': user.user_id, 'searches': user.searches } json_data = json.dumps(data) return HttpResponse(json_data, content_type='application/json') if request.method == 'POST': data = request.POST print(data) return HttpResponse("it worked")
前端SearchPage.js代码
useEffect(() => { console.log("user id changed") if (userId) { const user_profile_api_url = BASE_URL + '/users/' + userId axios.get(user_profile_api_url, {}) .then(response => { const recent_searches_response = response.data.searches; const new_recent_searches = []; recent_searches_response.map(dict => { new_recent_searches.push(dict.search_term) }) setRecentSearches(new_recent_searches); }) .catch((error) => { console.log("error in getting user profile: ", error.message) }) } }, [userId]) useEffect(() => { const user_profile_api_url = BASE_URL + '/users/' + userId const data = {searches: recentSearches} // axios.post(user_profile_api_url, { // params: { // searches: recentSearches // } // }) axios.post(user_profile_api_url, data) .then(response => { console.log(response) }) }, [recentSearches])
尝试过直接传递数据、用params包裹数据两种方式,均无效。怀疑@csrf_exempt有问题,但写法符合网上示例,需要在Django视图中获取POST请求里的recentSearches数据。
解决方案
问题核心:Axios默认以JSON格式发送POST数据(请求头Content-Type: application/json),但Django的request.POST仅处理application/x-www-form-urlencoded或multipart/form-data格式的数据,无法读取JSON请求体。
方法1:在Django视图中直接解析JSON请求体
修改POST分支代码,读取并解析请求体的JSON数据:
if request.method == 'POST': # 读取JSON格式请求体 data = json.loads(request.body) print(data) # 此时可获取{searches: [...]}结构数据 # 示例:更新UserProfile的searches字段 try: user = UserProfile.objects.get(user_id=user_id) # 转换为模型所需的格式(假设searches是JSONField) user.searches = [{'search_term': term} for term in data['searches']] user.save() except UserProfile.DoesNotExist: # 处理用户不存在的逻辑 pass return HttpResponse("it worked")
方法2:让Axios发送表单格式数据
若想继续用request.POST读取,可修改前端请求,将数据转为表单格式:
import qs from 'qs' // 需先安装qs库:npm install qs // 修改POST请求部分 axios.post(user_profile_api_url, qs.stringify(data), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
此方式下request.POST.get('searches')可获取数据,但表单格式对复杂数组结构支持有限,推荐使用方法1。
补充说明
@csrf_exempt无问题,它仅禁用CSRF校验,与数据读取逻辑无关。- 可通过浏览器网络请求头确认
Content-Type,对应选择数据读取方式。
内容的提问来源于stack exchange,提问作者codyc4321
相关产品推荐
相关产品推荐

