使用 REST Framework 在 Django 中从 POST 获取 JSON 数据
Get JSON data from POST in Django with REST Framework
我正在尝试在 Django 中构建一个 REST API 用于带有 Gspread 的 Google 电子表格,我 运行 遇到了很多问题(所以如果有人碰巧有一个完整的例子,随时分享......好吗?:))。其中一个问题是我正在尝试接收 JSON 的 POST 请求(当然,后来还有其他请求)。然而,这是失败的。这是我的代码:
view.py(我知道 IF 语句不是它的工作方式
elif request.method == 'POST':
received_json_data = json.loads(request.body.decode("utf-8"))
content = received_json_data['content']
if content != "":
worksheet.insert_row([content["date"], content["days"], content["firstname"], content["lastname"], content["team"], content["training"], content["company"], content["city"], content["cost"], content["invoice"], content["info"]], 1)
return JsonResponse(content, safe=False, status=status.HTTP_201_CREATED)
else:
return JsonResponse([], safe=False, status=status.HTTP_400_BAD_REQUEST)
为此编写的测试:
def test_post_all_training_returns_201_when_correct_format(self):
"""
A POST request on /trainings/ should create a new training
"""
headers = {'content-type': 'application/json'}
response = self.client.post('/trainings/', json=json.dumps(self.training_json_body), headers=headers, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
training_json_body的内容:
self.training_json_body = {
"date": "1/1/2018",
"days": 1,
"firstname": "Data",
"lastname": "Data",
"team": "Data",
"training": "Data",
"company": "Data",
"city": "Data",
"cost": 1,
"invoice": "Data",
"info": "Data"
}
回溯
Traceback (most recent call last):
File "C:\Python\backend\unleashedapp\trainings\tests.py", line 64, in test_post_all_training_returns_201_when_correct_format
response = self.client.post('/trainings/', json=json.dumps(self.training_json_body), headers=headers, format="json")
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 525, in post
response = super().post(path, data=data, content_type=content_type, secure=secure, **extra)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 341, in post
secure=secure, **extra)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 404, in generic
return self.request(**r)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 485, in request
raise exc_value
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py", line 35, in inner
response = get_response(request)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Python\backend\unleashedapp\trainings\views.py", line 36, in training_list
received_json_data = json.loads(request.body.decode("utf-8"))
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
我已经搜索了几天的解决方案,但无法正常工作,所以如果有人能将我推向正确的方向,我将非常感激。
我已将我的代码更新为以下内容:
class TrainingList(APIView):
def post(self, request, format=None):
sheet = request.GET.get('sheet', 'Data')
worksheet = spreadsheet.worksheet(sheet)
worksheet.append_row([request.data.get("date"), request.data.get("days"), request.data.get("firstname"), request.data.get("lastname"), request.data.get("team"), request.data.get("training"), request.data.get("company"), request.data.get("city"), request.data.get("cost"), request.data.get("invoice"), request.data.get("info")])
return JsonResponse("[]", safe=False, status=status.HTTP_201_CREATED)
这不再引发任何错误,但 append_row() 函数现在为每个字段添加 "None",因此很明显数据仍未通过。我该如何解决这个问题?
如果您使用的是 Django REST 框架,那么您可以通过访问 request.data
字典 (more info here) 轻松地从请求对象中获取数据。
如果您使用的是原始 Django 视图,则可以通过使用请求对象并访问 request.POST['<field_name>']
或 request.POST.get('<field_name>')
.
来访问 POST 数据
例如:
request.POST.get("date")
您可以阅读更多相关信息或查看示例 here。
试试这个:
request.data.get("sheet")
要获取 Json 格式的参数,您需要将请求的子方法从 "GET" 更改为 "DATA",如下所示:
sheet = request.data.get("sheet")
我正在尝试在 Django 中构建一个 REST API 用于带有 Gspread 的 Google 电子表格,我 运行 遇到了很多问题(所以如果有人碰巧有一个完整的例子,随时分享......好吗?:))。其中一个问题是我正在尝试接收 JSON 的 POST 请求(当然,后来还有其他请求)。然而,这是失败的。这是我的代码:
view.py(我知道 IF 语句不是它的工作方式
elif request.method == 'POST':
received_json_data = json.loads(request.body.decode("utf-8"))
content = received_json_data['content']
if content != "":
worksheet.insert_row([content["date"], content["days"], content["firstname"], content["lastname"], content["team"], content["training"], content["company"], content["city"], content["cost"], content["invoice"], content["info"]], 1)
return JsonResponse(content, safe=False, status=status.HTTP_201_CREATED)
else:
return JsonResponse([], safe=False, status=status.HTTP_400_BAD_REQUEST)
为此编写的测试:
def test_post_all_training_returns_201_when_correct_format(self):
"""
A POST request on /trainings/ should create a new training
"""
headers = {'content-type': 'application/json'}
response = self.client.post('/trainings/', json=json.dumps(self.training_json_body), headers=headers, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
training_json_body的内容:
self.training_json_body = {
"date": "1/1/2018",
"days": 1,
"firstname": "Data",
"lastname": "Data",
"team": "Data",
"training": "Data",
"company": "Data",
"city": "Data",
"cost": 1,
"invoice": "Data",
"info": "Data"
}
回溯
Traceback (most recent call last):
File "C:\Python\backend\unleashedapp\trainings\tests.py", line 64, in test_post_all_training_returns_201_when_correct_format
response = self.client.post('/trainings/', json=json.dumps(self.training_json_body), headers=headers, format="json")
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 525, in post
response = super().post(path, data=data, content_type=content_type, secure=secure, **extra)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 341, in post
secure=secure, **extra)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 404, in generic
return self.request(**r)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\test\client.py", line 485, in request
raise exc_value
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\exception.py", line 35, in inner
response = get_response(request)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Python\backend\unleashedapp\trainings\views.py", line 36, in training_list
received_json_data = json.loads(request.body.decode("utf-8"))
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\yanni\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
我已经搜索了几天的解决方案,但无法正常工作,所以如果有人能将我推向正确的方向,我将非常感激。
我已将我的代码更新为以下内容:
class TrainingList(APIView):
def post(self, request, format=None):
sheet = request.GET.get('sheet', 'Data')
worksheet = spreadsheet.worksheet(sheet)
worksheet.append_row([request.data.get("date"), request.data.get("days"), request.data.get("firstname"), request.data.get("lastname"), request.data.get("team"), request.data.get("training"), request.data.get("company"), request.data.get("city"), request.data.get("cost"), request.data.get("invoice"), request.data.get("info")])
return JsonResponse("[]", safe=False, status=status.HTTP_201_CREATED)
这不再引发任何错误,但 append_row() 函数现在为每个字段添加 "None",因此很明显数据仍未通过。我该如何解决这个问题?
如果您使用的是 Django REST 框架,那么您可以通过访问 request.data
字典 (more info here) 轻松地从请求对象中获取数据。
如果您使用的是原始 Django 视图,则可以通过使用请求对象并访问 request.POST['<field_name>']
或 request.POST.get('<field_name>')
.
例如:
request.POST.get("date")
您可以阅读更多相关信息或查看示例 here。
试试这个:
request.data.get("sheet")
要获取 Json 格式的参数,您需要将请求的子方法从 "GET" 更改为 "DATA",如下所示:
sheet = request.data.get("sheet")