'How to wait in django until a request for endpoint arrives?
Tell me with what you can wait for a response to another endpoint? I am on the main page (index), entering something into the form. The POST request is sent to another server. At this moment:
- another server processes the data and, depending on their correctness, makes a POST request to my url /answer (True or False).
- I will be redirected, for example, to another page. How to register the logic of another page (another) so that Django waits for a POST request from another server to /answer and depending on this request True/False, I output everything OK or everything Bad on this page?
url.py
urlpatterns = [
path('index/', index, name='index'),
path('page_2/', page_2, name='page_2'),
path('answer/', answer, name='answer'),
]
-------------------------------------------------
views.py
def index(request):
requests.post(example.com, data='My data')
return redirect('page_2')
def page_2(request):
# wait request in answer
if request.session['answer'] is True:
return 'Ok'
retunr 'Bad'
def answer(request):
data = request.data
# send to page_2 or save in request.session['answer']
return Response(status=200)
Solution 1:[1]
I reckon it's a strange situation and it's better if you could redesign the logic of your code so that the view functions process the request ASAP and not busily wait for external events to be triggered as it increases response time.
However, in order to achieve this purpose we need a communication channel between index and answer view. So to implement a communication like this:
index: Heyanswer! I've sent the request. I'm going to sleep, wake me up if you got its result.answer: Oh I got it man. Here you are. Wake up!index: Thanks. Now I process it and return my response.
So this channel might be anything! A model in database, some entities in redis, some files in filesystem, etc.
One possible solution using the models might be:
- Create a model(name it
ExampleRequestfor example) consisting of a boolean field namedreceived - In
indexview, create an instance ofExampleRequestwithreceived = Falsebefore sending the request. - In
answerview, find the previously createdExampleRequestand set itsreceivedfield toTrue - In
indexview, after sending the request, in a while loop, query the database and check if the createdExampleRequestinstance hasreceived = True? If yes, then the external server has calledanswer. So break the while and do the rest of the work; otherwise, justtime.sleep(1)and continue the while loop.
Just note:
- When multiple clients are using your website, some of them might request
indexview and then there will be more than one instance ofExampleRequest. Inanswerview, you have to be able to find out the current request is related to which one of those instances. You might need to store a unique data related to that request inExampleRequestmodel. - You might consider the situation where the other server doesn't call
answerview ever. So there might be an upper bound for the iterations ofindexview's while loop. - Also you may remove
ExampleRequestinstances after capturing them inindexview in order to optimize disk usage of your database.
I say it again, it's better if you can do the polling stuff in frontend instead of backend to avoid high response time and other syncing issues.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
