简体   繁体   English

执行非阻塞请求? -Django

[英]Performing non-blocking requests? - Django

I have been playing with other frameworks, such as NodeJS, lately. 最近,我一直在使用其他框架,例如NodeJS。

I love the possibility to return a response, and still being able to do further operations. 我喜欢返回响应并仍然可以执行进一步操作的可能性。

eg 例如

def view(request):
  do_something()
  return HttpResponse()

  do_more_stuff() #not possible!!!

Maybe Django already offers a way to perform operations after returning a request, if that is the case that would be great. 也许Django已经提供了一种在返回请求后执行操作的方法,如果这种情况很好。


Help would be very much appreciated! 帮助将不胜感激! =D = D

not out of the box as you've already returned out of the method. 不要直接使用,因为您已经退出了方法。 You could use something like Celery which would pass the do_more_stuff task onto a queue and then have it run do_more_stuff() outside of http request / response flow. 您可以使用像Celery这样的东西,它将do_more_stuff任务传递到队列中,然后使其在http请求/响应流之外运行do_more_stuff()

Django lets you accomplish this with Signals, more information can be found here . Django使您可以使用Signals完成此操作,更多信息可以在此处找到。 (Please note, as I said in comments below, signals aren't non-blocking, but they do allow you to execute code after returning a response in a view.) (请注意,正如我在下面的评论中所述,信号并不是非阻塞的,但它们确实允许您在视图中返回响应后执行代码。)

If you're looking into doing many, many asynchronous requests and need them to be non-blocking, you may want to check out Tornado . 如果您正在考虑执行许多异步请求,并且希望它们是非阻塞的,那么您可能想看看Tornado

Because you're returning from the function, do_more_stuff will never be called. 因为您要从函数返回,所以永远不会调用do_more_stuff。

If you're looking at doing heavy lifting stuff queuing up something before you return as Ross suggests (+1 for Celery). 如果您正在考虑做一些繁重的工作,请按照罗斯的建议在排队之前先排队(Celery +1)。

if however you're looking at returning some content... then doing something and returning more content to the user streaming is probably what you're looking for. 但是,如果您正在寻找返回某些内容...,那么您可能正在寻找做某件事并将更多内容返回给用户流。 You can pass an iterator or a generator to HttpResponse, and it'll iterate and push out the content in a trickle fashion. 您可以将迭代器或生成器传递给HttpResponse,它将以点滴的方式迭代并推出内容。 It feels a bit yuck, but if you're a generator rockstar you may be able to do enough in various states to accomplish what you want. 感觉有点不对劲,但是如果您是发电机摇滚明星,则可以在各种状态下完成足够的工作来完成您想要的。

Or I guess you could simply redesign your page to use a lot of ajax to do what you need, including firing off events to django views, reading data from views, etc. 或者我想您可以简单地重新设计页面,以使用大量的ajax来完成所需的工作,包括将事件触发到django视图,从视图中读取数据等。

It kind of comes down to where the burden of async is going to sit: client, server or response. 归结为异步负担的重担:客户端,服务器或响应。

I'm not that familiar with node.js yet, but it would be interesting to see the use case you're talking about. 我还不太熟悉node.js,但是看到您正在谈论的用例将很有趣。

EDIT: I did a little more looking into signals, and while they do occur in process, there is a built in signal for request_finished after the request has been handled by django, though it's more of a catchall than something specific. 编辑:我做了一些调查信号,虽然它们确实发生在过程中,但在django处理了请求之后,有一个内置的request_finished信号,尽管它比特定的东西更笼统。

You can use threading as a temporary fix or as a non-production solution but it is neither scalable nor the best practice. 您可以将线程用作临时修复程序或非生产解决方案,但它既不可扩展,也不是最佳实践。 Use celery for better design! 使用芹菜进行更好的设计!

def foo(request):
    import threading
    from time import sleep
    def foo():
        sleep(5)
        # Do something
        print('hello, world')
    threading.Thread(target=foo).start()
    return JsonResponse(data={'detail': 'thread started'})

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

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