简体   繁体   English

为什么Python请求库无法获得响应?

[英]Why Python requests library failing to get response?

I have a view method: 我有一个查看方法:

# 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})

Here in the above mentioned view method, the requests library just keeps on loading and just doesnt get the response and ultimately fails after 10 secs as timedout. 在上面提到的view方法中,请求库只是继续加载而没有得到响应,并最终在超时10秒后失败。

The other app where 'api/create-user/' url maps to is in the same project, could this be the reason? “ api / create-user /” URL映射到的另一个应用程序在同一项目中,这可能是原因吗?

The url for that mapping in that app urls.py (not main urls.py) is : 该应用程序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),
]

I am also using Django rest framework and the view which the above mentioned url matches to is: 我还使用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)

With the unit testing it works fine, here is the unit test which I wrote: 使用单元测试,它可以正常工作,这是我写的单元测试:

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")

I have also added few settings such as ALLOWED_HOSTS etc. in settings.py and for django rest framework I added: 我还在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']

What am I doing wrong here? 我在这里做错了什么? Thanks 谢谢


I also tried using requests from manage.py shell, and it seems to work fine there. 我也尝试过使用来自manage.py shell的请求,并且在这里似乎工作正常。 Is it because I am using it inside a form.is_valid() block that it is not working or I also suspect django-rest-framework to be the culprit. 是因为我在form.is_valid()块中使用了它而不起作用,还是怀疑django-rest-framework是罪魁祸首。 Is there any settings which I need to add more? 是否需要添加更多设置?

---------- Answer ---------- 回答


I was using runserver_plus which is not multithreaded, to solve this problem I am using runserver and it works fine, otherwise you have to start same project on two different ports! 我正在使用不是多线程的runserver_plus来解决此问题,所以我正在使用runserver并且它运行良好,否则,您必须在两个不同的端口上启动同一项目!

I believe this is because you are using the Django runserver (correct me if I am wrong) which is not multi-threaded 我相信这是因为您正在使用不是多线程的Django Runserver(如果我输入错误,请更正我)

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

So you request to localhost:8000 is queued waiting for the request that made the request to finish! 因此,您对localhost:8000的请求已排队,等待使请求完成的请求! Not ideal. 不理想。

In production, where you are running your server with a wsgi app (like uwsgi) this would be OK because it is multithreaded. 在生产中,使用wsgi应用程序(例如uwsgi)运行服务器的地方可以,因为它多线程的。

The reason it works in this test case is because you are making the request from the test thread to the test server that is being run in a different thread. 它工作在这个测试案例的原因是因为你正在从测试线程在不同的线程中运行测试服务器的请求。

EDIT #1: A few things to think about 编辑#1:需要考虑的几件事

1) Why are your accepting your registration form in a GET request and not a POST request? 1)为什么您在GET请求而不是POST请求中接受注册表格? This is an abuse of the GET verb because you are actually creating something on the server 这是对GET动词的滥用,因为您实际上是在服务器上创建内容

2) Why are you calling your own API from inside your application and not putting this functionality into a method that can be called from all endpoints that need it? 2)为什么要从应用程序内部调用自己的API,而不是将此功能放入可从需要它的所有端点调用的方法中?

EDIT #2: 编辑#2:

As stated in the comments, the dev server is multithreaded 如评论中所述,开发服务器多线程的

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM