【问题标题】:Why Python requests library failing to get response?为什么 Python 请求库没有得到响应?
【发布时间】:2016-12-23 02:51:15
【问题描述】:

我有一个视图方法:

# This view method is to register a new user through api call
def register(request):
    if request.method == 'GET':
        registrationForm = RegistrationForm(request.GET)

        if registrationForm.is_valid():

            r = requests.get('http://localhost:8000/api/create-user/', timeout=10)
            print r.content
            return HttpResponseRedirect('/')
    else:
        registrationForm = RegistrationForm()

    return render(request, 'frontend/index.html', {'registrationForm': registrationForm})

在上面提到的视图方法中,请求库只是继续加载,只是没有得到响应,最终在 10 秒后超时失败。

'api/create-user/' url 映射到的另一个应用程序在同一个项目中,这可能是原因吗?

该应用程序 urls.py(不是主 urls.py)中该映射的 url 是:

from django.conf.urls import include, url
from django.contrib import admin

from . import views

urlpatterns = [
    url(r'^create-user/', views.create_user),
]

我也在使用Django rest框架,上面提到的url匹配的视图是:

from django.shortcuts import render

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response


# Create your views here.
@api_view(['GET'])
def create_user(request):
    print 'coming....'
    # print request.GET.get('username')
    # print request.POST.get('password')
    data = {}

    data.update({'result': 'good'})

    return Response(data)

通过单元测试它工作正常,这是我编写的单元测试:

from django.test import TestCase

import requests

# Create your tests here.
# This class is for unit testing the request/response for api module.
# Here we can test if the REST api call we are making are working perfect or not.
class FrontEndTests(TestCase):

    def test_user_creation(self):
        r = requests.get('http://localhost:8000/api/create-user/')
        print r.content
        self.assertIsNotNone(r, "Not none")

我还在 settings.py 中添加了一些设置,例如 ALLOWED_HOSTS 等,并为 django rest 框架添加了:

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}

SESSION_SAVE_EVERY_REQUEST = True

ALLOWED_HOSTS = ['localhost', '127.0.0.1']

我在这里做错了什么? 谢谢


我还尝试使用来自 manage.py shell 的请求,它似乎在那里工作正常。 是因为我在 form.is_valid() 块中使用它不起作用还是我也怀疑 django-rest-framework 是罪魁祸首。有什么需要我添加的设置吗?

---------- 回答


我使用的是非多线程的runserver_plus,为了解决这个问题,我使用的是runserver,它工作正常,否则你必须在两个不同的端口上启动同一个项目!

【问题讨论】:

  • 如果你设置了超时,你的单元测试是否通过?
  • @JuanTomas 是的。我刚刚测试过。
  • 请粘贴requests.get调用超时时的回溯。
  • 为什么要通过 API 调用自己的应用程序?重点是什么?为什么不直接调用方法呢?
  • @DanielRoseman 它的原型。

标签: django python-2.7 django-rest-framework python-requests django-1.8


【解决方案1】:

我相信这是因为您使用的不是多线程的 Django 运行服务器(如果我错了,请纠正我)

https://code.djangoproject.com/ticket/3357

因此,您对 localhost:8000 的请求正在排队等待使请求完成的请求!不理想。

在生产环境中,您正在使用 wsgi 应用程序(如 uwsgi)运行服务器,这没问题,因为它是多线程的。

它在这个测试用例中起作用的原因是因为您正在从测试线程向测试服务器发出请求, 在不同的线程中运行。

编辑 #1:需要考虑的几件事

1) 为什么您在 GET 请求而不是 POST 请求中接受您的注册表单?这是对 GET 动词的滥用,因为您实际上是在服务器上创建一些东西

2) 为什么要从应用程序内部调用自己的 API,而不是将此功能放入可以从所有需要它的端点调用的方法中?

编辑#2:

如 cmets 中所述,开发服务器 是多线程的

https://github.com/django/django/commit/ce165f7bbf

【讨论】:

  • 我见过同一张票,然后我在 django 文档中看到here 开发服务器默认是多线程的。
  • 啊,我说得对(我确实注意到这是一张很旧的票,但在 Django 票中“不会修复”标签通常值得关注)
  • 是的,这是添加它的提交github.com/django/django/commit/ce165f7bbf
  • 你说得有道理,我在谷歌上进行了更多研究,得出了同样的结论。关于你的另外两点,1.它的POST,我只是为了测试目的把它改成了GET和POST,但我现在把它改回了POST。 2.这是一个原型,所以我不太在乎正确的方法。但是默认情况下开发服务器不是多线程的吗?虽然我设法通过在不同的端口运行同一个项目来完成这项工作!!
  • 实际上这是我的一个愚蠢的错误,即使知道答案我也没有做对。我编辑了我的问题并将您的问题标记为答案,因为您指导的方向正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
  • 2016-03-30
相关资源
最近更新 更多