apache2 上的 django rest framework 运行 未向客户端返回完整响应
django rest framework running on apache2 not returning full response to client
我是 运行 api apache/2.4.29 在 wsgi 上使用 django 2.2.5 运行 之上的 django rest 框架 3.10.3 构建,每当我尝试 return json object 来自客户端的 POST 请求时,apiviews.py 中描述成功的 POST 方法不会发送完整的数据。我试过使用 curl、postman 和 insomina,结果是一样的。在日志中显示 returning 响应 object 已完全发送。
这是 apiviews.py 代码:
from rest_framework import generics, status, viewsets, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from django.shortcuts import get_object_or_404, get_list_or_404
from django.contrib.auth import authenticate
import threading
import datetime
import json
from commons.models import SMSMessages
from commons.serializers import SMSMessagesSerializer
from notification.sender import sender
class SMSView(APIView):
def post(self, request):
sms_messages_serializer = SMSMessagesSerializer(
data={
"sms_number_to": request.data.get("sms_number_to"),
"sms_content": request.data.get("sms_content"),
"sending_user": request.auth.user_id,
}
)
permission_classes = (permissions.IsAuthenticated)
if sms_messages_serializer.is_valid():
data_to_send = {
"number": sms_messages_serializer.validated_data[
"sms_number_to"
],
"msg_text": sms_messages_serializer.validated_data[
"sms_content"
]
}
sms_object = sms_messages_serializer.save()
else:
print("invalid data - {0}\t{1}".format(sms_messages_serializer.errors, datetime.datetime.now()))
data_to_send = None
max_retry = 0
resp = Response()
while max_retry < 3:
max_retry += 1
status_flag, status_response = sender(data_to_send)
if not status_flag:
resp = Response(
data={
"status": "sms not sent"
},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
content_type="application/json"
)
else:
# the update method defined in the SMSMessagesSerializer class
# needs an instance to work with.
sms_messages_serializer.update(
sms_object,
{
"delivery_status": True
}
)
resp = Response(
data={
"status": "sms successfully sent"
},
headers=status_response.headers,
status=status_response.status_code,
content_type="application/x-www-form-urlencoded"
)
print(resp.data)
return resp
else:
resp = Response(
data={
"error": "unable to send sms"
},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
content_type="application/json"
)
print(resp.data)
return resp
当短信发送成功后,在日志文件中打印出:
[Wed Dec 23 14:19:29.789772 2020] [wsgi:error] [pid 27330] [remote xxx.xxx.xxx.xxx:xxxx] {'status': 'sms successfully sent.'}
但这不是交付给客户端的内容,客户端应用程序收到:
{"status":"sms successfull
为了更清楚起见,这是 sender
模块——它使用 python 请求库:
import requests
import time
import json
from rest_framework.response import Response
from rest_framework import status
base_url = "http://xxx.xxx.xxx.xxx:xxxx/"
def sender(sms_data):
"""
The actual function that accesses the server and sends the sms.
"""
sending_url = base_url + "api/sendsms/"
sending_headers = {"content-type": "application/x-www-form-urlencoded"}
response = requests.Response()
try:
response = requests.post(
sending_url,
data=sms_data,
headers=sending_headers,
timeout=(7, 14),
)
response.raise_for_status()
except Exception as e:
print("{}".format(e))
return False, response
else:
return True, response
在所有 headers 完好无损的情况下,这只会出现在成功响应中,不会出现在其余响应中。
如何让它向客户端发送完整的响应?
谢谢
headers设置成功后响应提示错误Content-Length和Content-Type。
您的回复目前是这样构建的:
resp = Response(
data={
"status": "success"
},
headers=status_response.headers,
status=status_response.status_code,
content_type="application/form-data"
)
您正在转发 headers 来自 SMS 服务的响应,例如 Content-Length
,而传输的内容是 {"status": "success"}
。
当构建响应中未提供Content-Length
时,框架会根据传输的内容进行计算。
还有一点要注意,传输的内容是JSON数据而不是form-data
。
如果您关心短信服务响应中的任何特定headers,我建议明确选择将哪个headers发送回请求者,如下所示:
resp = Response(
data={
"status": "success"
},
headers={
"specific_header_name_passed_from_sms_service": status_response.headers["specific_header_name_passed_from_sms_service"],
#...
},
status=status_response.status_code,
content_type="application/json"
)
否则,如果您不关心 SMS 服务响应中的任何 headers,您可以忽略在内置响应中传递 headers
选项。
我是 运行 api apache/2.4.29 在 wsgi 上使用 django 2.2.5 运行 之上的 django rest 框架 3.10.3 构建,每当我尝试 return json object 来自客户端的 POST 请求时,apiviews.py 中描述成功的 POST 方法不会发送完整的数据。我试过使用 curl、postman 和 insomina,结果是一样的。在日志中显示 returning 响应 object 已完全发送。 这是 apiviews.py 代码:
from rest_framework import generics, status, viewsets, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from django.shortcuts import get_object_or_404, get_list_or_404
from django.contrib.auth import authenticate
import threading
import datetime
import json
from commons.models import SMSMessages
from commons.serializers import SMSMessagesSerializer
from notification.sender import sender
class SMSView(APIView):
def post(self, request):
sms_messages_serializer = SMSMessagesSerializer(
data={
"sms_number_to": request.data.get("sms_number_to"),
"sms_content": request.data.get("sms_content"),
"sending_user": request.auth.user_id,
}
)
permission_classes = (permissions.IsAuthenticated)
if sms_messages_serializer.is_valid():
data_to_send = {
"number": sms_messages_serializer.validated_data[
"sms_number_to"
],
"msg_text": sms_messages_serializer.validated_data[
"sms_content"
]
}
sms_object = sms_messages_serializer.save()
else:
print("invalid data - {0}\t{1}".format(sms_messages_serializer.errors, datetime.datetime.now()))
data_to_send = None
max_retry = 0
resp = Response()
while max_retry < 3:
max_retry += 1
status_flag, status_response = sender(data_to_send)
if not status_flag:
resp = Response(
data={
"status": "sms not sent"
},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
content_type="application/json"
)
else:
# the update method defined in the SMSMessagesSerializer class
# needs an instance to work with.
sms_messages_serializer.update(
sms_object,
{
"delivery_status": True
}
)
resp = Response(
data={
"status": "sms successfully sent"
},
headers=status_response.headers,
status=status_response.status_code,
content_type="application/x-www-form-urlencoded"
)
print(resp.data)
return resp
else:
resp = Response(
data={
"error": "unable to send sms"
},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
content_type="application/json"
)
print(resp.data)
return resp
当短信发送成功后,在日志文件中打印出:
[Wed Dec 23 14:19:29.789772 2020] [wsgi:error] [pid 27330] [remote xxx.xxx.xxx.xxx:xxxx] {'status': 'sms successfully sent.'}
但这不是交付给客户端的内容,客户端应用程序收到:
{"status":"sms successfull
为了更清楚起见,这是 sender
模块——它使用 python 请求库:
import requests
import time
import json
from rest_framework.response import Response
from rest_framework import status
base_url = "http://xxx.xxx.xxx.xxx:xxxx/"
def sender(sms_data):
"""
The actual function that accesses the server and sends the sms.
"""
sending_url = base_url + "api/sendsms/"
sending_headers = {"content-type": "application/x-www-form-urlencoded"}
response = requests.Response()
try:
response = requests.post(
sending_url,
data=sms_data,
headers=sending_headers,
timeout=(7, 14),
)
response.raise_for_status()
except Exception as e:
print("{}".format(e))
return False, response
else:
return True, response
在所有 headers 完好无损的情况下,这只会出现在成功响应中,不会出现在其余响应中。
如何让它向客户端发送完整的响应?
谢谢
headers设置成功后响应提示错误Content-Length和Content-Type。
您的回复目前是这样构建的:
resp = Response(
data={
"status": "success"
},
headers=status_response.headers,
status=status_response.status_code,
content_type="application/form-data"
)
您正在转发 headers 来自 SMS 服务的响应,例如 Content-Length
,而传输的内容是 {"status": "success"}
。
当构建响应中未提供Content-Length
时,框架会根据传输的内容进行计算。
还有一点要注意,传输的内容是JSON数据而不是form-data
。
如果您关心短信服务响应中的任何特定headers,我建议明确选择将哪个headers发送回请求者,如下所示:
resp = Response(
data={
"status": "success"
},
headers={
"specific_header_name_passed_from_sms_service": status_response.headers["specific_header_name_passed_from_sms_service"],
#...
},
status=status_response.status_code,
content_type="application/json"
)
否则,如果您不关心 SMS 服务响应中的任何 headers,您可以忽略在内置响应中传递 headers
选项。