首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在apache2上运行的django rest框架没有向客户端返回完全响应

在apache2上运行的django rest框架没有向客户端返回完全响应
EN

Stack Overflow用户
提问于 2020-12-23 14:35:36
回答 1查看 200关注 0票数 1

我在apache/2.4.29上运行一个api,它使用django rest框架3.10.3构建在运行在wsgi上的django 2.2.5之上,每当我试图为来自客户端的POST请求返回json对象时,描述成功的apiviews.py中的POST方法不会发送完整的数据。我试过使用卷发,邮递员和失眠症,反应是一样的。在日志中,它显示返回的Reponse对象被完全发送。这是apiviews.py代码:

代码语言:javascript
复制
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

当sms成功发送时,它会在日志文件上打印出:

代码语言:javascript
复制
[Wed Dec 23 14:19:29.789772 2020] [wsgi:error] [pid 27330] [remote xxx.xxx.xxx.xxx:xxxx] {'status': 'sms successfully sent.'}

但这不是交付给客户端的内容,客户端应用程序接收到:

代码语言:javascript
复制
{"status":"sms successfull

为了更清晰起见,这是一个sender模块--它使用python库:

代码语言:javascript
复制
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

所有标头都完好无损,这只发生在成功响应上,其余的则不会出现。

如何使它向客户端发送完整的响应?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-03 10:16:02

在成功响应上设置的标头通知错误的内容长度和内容类型。

您的响应目前是这样构建的:

代码语言:javascript
复制
resp = Response(
    data={
        "status": "success"
    },
    headers=status_response.headers,
    status=status_response.status_code,
    content_type="application/form-data"
)

在这里,您从短信服务(如Content-Length )转发响应的头,而传输的内容是{"status": "success"}

当构建的响应中没有提供Content-Length时,框架将根据传输的内容计算它。

还需要注意的是,传输的内容是JSON数据,而不是form-data

如果您关心SMS服务响应中的任何特定标头,建议显式地选择将哪些标头发送回请求者,如下所示:

代码语言:javascript
复制
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选项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65426021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档