在继续完成与请求关联的任务之前,django如何提供HTTP响应? [英] How to have django give a HTTP response before continuing on to complete a task associated to the request?

查看:123
本文介绍了在继续完成与请求关联的任务之前,django如何提供HTTP响应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的django活塞API中,我想在调用另一个将花费相当时间的函数之前让/返回HTTP响应给客户端。如何使yield给出一个HTTP响应,其中包含所需的JSON而不是与生成器对象的创建有关的字符串?

In my django piston API, I want to yield/return a http response to the the client before calling another function that will take quite some time. How do I make the yield give a HTTP response containing the desired JSON and not a string relating to the creation of a generator object?

我的活塞处理程序方法如下所示:

My piston handler method looks like so:

def create(self, request):
    data = request.data 

    *other operations......................*

    incident.save()
    response = rc.CREATED
    response.content = {"id":str(incident.id)}
    yield response
    manage_incident(incident)

而不是我想要的响应,例如:

Instead of the response I want, like:

   {"id":"13"}

客户得到这样的字符串:

The client gets a string like this:

 "<generator object create at 0x102c50050>"

编辑:

我意识到使用yield是解决此问题的错误方法,从本质上讲,我试图实现的是客户端立即收到响应,然后服务器将其转移到耗时的manage_incident()函数上

I realise that using yield was the wrong way to go about this, in essence what I am trying to achieve is that the client receives a response right away before the server moves onto the time costly function of manage_incident()

推荐答案

这与生成器或yield无关,但是我使用了以下代码和装饰器来运行它们

This doesn't have anything to do with generators or yielding, but I've used the following code and decorator to have things run in the background while returning the client an HTTP response immediately.

用法:

@postpone
def long_process():
    do things...

def some_view(request):
    long_process()
    return HttpResponse(...)

这是使其工作的代码:

import atexit
import Queue
import threading

from django.core.mail import mail_admins


def _worker():
    while True:
        func, args, kwargs = _queue.get()
        try:
            func(*args, **kwargs)
        except:
            import traceback
            details = traceback.format_exc()
            mail_admins('Background process exception', details)
        finally:
            _queue.task_done()  # so we can join at exit

def postpone(func):
    def decorator(*args, **kwargs):
        _queue.put((func, args, kwargs))
    return decorator

_queue = Queue.Queue()
_thread = threading.Thread(target=_worker)
_thread.daemon = True
_thread.start()

def _cleanup():
    _queue.join()   # so we don't exit too soon

atexit.register(_cleanup)

这篇关于在继续完成与请求关联的任务之前,django如何提供HTTP响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆