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.
The other app where 'api/create-user/' url maps to is in the same project, could this be the reason?
The url for that mapping in that app urls.py (not main urls.py) is :
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:
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:
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. 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. 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!
I believe this is because you are using the Django runserver (correct me if I am wrong) which is not multi-threaded
https://code.djangoproject.com/ticket/3357
So you request to localhost:8000 is queued waiting for the request that made the request to finish! Not ideal.
In production, where you are running your server with a wsgi app (like uwsgi) this would be OK because it is multithreaded.
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) Why are your accepting your registration form in a GET request and not a POST request? This is an abuse of the GET verb because you are actually creating something on the server
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?
EDIT #2:
As stated in the comments, the dev server is multithreaded
来源:https://stackoverflow.com/questions/38979817/why-python-requests-library-failing-to-get-response