如果您在代码中使用 request.POST 来访问 HTTP POST 正文值,请注意https://www.django-rest-framework.org/tutorial/2-requests-and-responses/中所述
request.POST # 只处理表单数据。仅适用于“POST”方法。
如果您希望您的视图能够同时从 form-data(或 x-www-form-urlencoded)和 raw(JSON 格式)读取 HTTP POST 正文值,那么您不能使用 request.单独发布。你可以:
- 从 request.body 读取
- 从 request.data 读取(仅当逻辑在 rest_framework 下才可用)
示例
urls.py
path('printpostedvalues/', printpostedvalues_view),
views.py
@csrf_exempt
def printpostedvalues_view(request):
print("request.body", request.body)
try:
print("json.loads(request.body)", json.loads(request.body))
for k, v in json.loads(request.body).items():
print("json.loads(request.body)", k, "-->", v)
except Exception:
print("request.body's string value is not in the format of JSON key:value pairs")
print("request.POST", request.POST)
for k, v in request.POST.items():
print("request.POST", k, "-->", v)
return HttpResponse("Printed values in console...")
使用 Postman 执行 HTTP POST http://127.0.0.1:8000/printpostedvalues/。
案例一:表单数据
HTTP 正文
KEY - VALUE
athlete - LeBron James
status - GOAT!
quote - Strive for greatness
控制台输出
request.GET <QueryDict: {}>
request.body b'----------------------------269460357877673035654590\r\nContent-Disposition: form-data; name="athlete"\r\n\r\nLeBron James\r\n----------------------------269460357877673035654590\r\nContent-Disposition: form-data; name="status"\r\n\r\nGOAT!\r\n----------------------------269460357877673035654590\r\nContent-Disposition: form-data; name="quote"\r\n\r\nStrive for greatness\r\n----------------------------269460357877673035654590--\r\n'
request.body's string value is not in the format of JSON key:value pairs
request.POST <QueryDict: {'athlete': ['LeBron James'], 'status': ['GOAT!'], 'quote': ['Strive for greatness']}>
request.POST athlete --> LeBron James
request.POST status --> GOAT!
request.POST quote --> Strive for greatness
[11/Mar/2020 04:57:43] "POST /printpostedvalues/ HTTP/1.1" 200 28
结论:
request.body 包含来自表单数据的 HTTP POST 信息,但显然不是 JSON 格式,因此无法通过 json.loads() 解析。 request.POST 也包含这些值。
案例 2:x-www-form-urlencoded
HTTP 正文
与案例 1 相同
控制台输出
与案例 1 相同,但第 2 行 - request.body b'athlete=LeBron%20James&status=GOAT%21&quote=Strive%20for%20greatness'
结论:
与案例 1 相同
案例 3:原始 (JSON)
HTTP 正文
{
"athlete" : "LeBron James",
"status" : "GOAT!",
"quote" : "Strive for greatness"
}
控制台输出
request.GET <QueryDict: {}>
request.body b'{\n "athlete" : "LeBron James",\n "status" : "GOAT!",\n "quote" : "Strive for greatness"\n}'
json.loads(request.body) {'athlete': 'LeBron James', 'status': 'GOAT!', 'quote': 'Strive for greatness'}
json.loads(request.body) athlete --> LeBron James
json.loads(request.body) status --> GOAT!
json.loads(request.body) quote --> Strive for greatness
request.POST <QueryDict: {}>
结论:
request.body 包含来自原始 JSON 数据的 HTTP POST 信息,并且是 JSON 格式,因此可以通过 json.loads() 进行解析。 request.POST 不包含任何值。
总结
长话短说,如果您希望 HTTP POST 正文值不仅作为表单数据而且作为原始 JSON 格式出现,请不要依赖 request.POST。如果您为此使用 rest_framework,最好的选择是使用 request.data,因为它能够捕获来自 HTTP POST 的所有信息,无论格式如何。