从浏览器杀死Django进程

时间:2016-04-14 06:13:36

标签: python django http-post

在Django视图中,我调用了一个上传和导入excel文件的函数。

def import_log(request):
    report = ""

    if request.method == "POST":
        file_object = request.FILES
        sheet_name = request.POST["sheet_name"]

        if len(file_object):
            file_object = file_object["file_object"]

        if len(file_object):
            process_import()

            context = {
                "report": report
            }

            return render(request, "import_log.html", context)

        else:
            return import_upload_view(request, error="No file uploaded")

当我尝试通过单击“停止加载此页面”或关闭浏览器来停止页面时,导入过程不会停止。

这些导入文件非常大,所以我希望能够在需要时从浏览器中删除该进程。

我怎么能这样做?

2 个答案:

答案 0 :(得分:4)

简单地说,你做不到。

互联网的工作原理是向服务器发送请求,然后等待响应,它不属于与进程的开放连接,这就是服务器处理自己进程的工作。

浏览器基本上只是您的计算机显示器,显示发送给它的信息 - 因此您可以关闭显示器或拔掉插头,它不会阻止您的计算机运行< / p>

答案 1 :(得分:0)

Django /服务器唯一能够知道'中止连接'的时候是它尝试发送响应的时候。要理解这一点,你可以写一个虚拟视图,并在该视图中休眠10秒;从浏览器中调用它并尽可能快地停止它;等着看看Django的作用。如果您正在运行Django Dev服务器,那么您应该清楚Django的行为正常并发送响应但由于连接中止而发生500错误,然后尝试将此500错误发送给客户端,当然显然也会失败。

因此,无法在中间停止查看过程。

但是,您可以通过首先将请求发送到您的视图然后分拆新进程来执行“相当大”的导入过程来改变您解决此问题的方式;通过在某些持久性数据存储(可能在数据库中)中使用一些唯一ID和当前时间戳来注册该进程;返回带有注册ID的HTTP状态代码202(已接受)以结束视图。

在旋转过程中,有多线程。一个线程连续轮询数据库以检查当前时间与数据库中的时间之间的增量。如果差异超过您决定的阈值(比如10秒),整个过程就会自行消失。

从浏览器继续点击API(另一个Django视图),使用AJAX更新数据库中特定记录的时间戳,其ID是202响应中的ID。

我们的想法是让我们知道客户端仍然可用的服务器,如果由于某种原因你没有看到来自客户端的任何ping,你会将其视为浏览器关闭或离开页面的情况,因此停止在这个过程中分离出来。

如果您是单页应用程序,这种方法可能会变得棘手。