使用requests库向Django REST API传递JSON负载时的问题
Django REST API 请求体为空问题排查与解决
我刚入门Django REST API,学习时遇到了问题:客户端发送的JSON数据无法被后端接收到,request.body始终为空,且content_type不符合预期。
原始代码
客户端代码
import requests endpoint = "http://127.0.0.1:8000/api" get_response = requests.get(endpoint, params={"abc":123}, json={'query' : 'HELLO WORLD!!'}) print(get_response.json())
API后端代码
from django.http import JsonResponse import json def api_home(request): body = request.body print(body) # 实际输出b''而非预期的b'{"query": "HELLO WORLD!!"}' data = {} try: data = json.loads(body) except Exception as e: print(e) # 抛出异常:Expecting value: line 1 column 1 (char 0) print(data) # 返回{} data["content_type"] = request.content_type # 实际返回text/plain而非application/json return JsonResponse(data)
修改后的代码(问题仍存在)
客户端代码
import requests import json endpoint = "http://127.0.0.1:8000/api" payload = {'query': 'HELLO WORLD!!'} headers = {'Content-Type': 'application/json'} get_response = requests.get(endpoint, params={"abc": 123}, data=json.dumps(payload), headers=headers) print(get_response.text)
API后端代码
from django.http import JsonResponse import json def api_home(request): data = {} try: data = json.loads(request.body) except Exception as e: print(e) print(data) data["content_type"] = request.content_type return JsonResponse(data)
错误原因及解决方法
核心问题
GET请求通常不携带请求体,虽然HTTP规范未完全禁止,但多数HTTP客户端(包括requests库)和服务器框架对GET请求的请求体支持有限,甚至直接忽略。这就是你的JSON数据未出现在request.body中、content_type不符合预期的原因。
解决方法
方法1:改用POST请求(推荐)
RESTful API中,POST请求是提交数据的标准方式,能正常传递请求体。修改客户端代码为POST请求:
import requests endpoint = "http://127.0.0.1:8000/api" get_response = requests.post(endpoint, params={"abc":123}, json={'query' : 'HELLO WORLD!!'}) print(get_response.json())
后端代码无需修改,此时request.body会正确接收JSON数据,content_type也会自动设为application/json。
方法2:将数据放在URL查询参数中(适配GET场景)
如果业务逻辑必须使用GET请求,可将数据转为查询参数传递:
import requests endpoint = "http://127.0.0.1:8000/api" get_response = requests.get(endpoint, params={"abc":123, "query": "HELLO WORLD!!"}) print(get_response.json())
后端通过request.GET获取参数:
from django.http import JsonResponse def api_home(request): data = request.GET.dict() data["content_type"] = request.content_type return JsonResponse(data)
方法3:强制处理GET请求的请求体(不推荐)
若一定要用GET携带请求体,需确保服务器端能正确解析,但这种方式不符合REST规范,兼容性差,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者SHaD0W
相关产品推荐
相关产品推荐

