3

我有一个 Django 应用程序,该应用程序需要在上传多部分文件时将其作为类文件对象读取这意味着我需要或多或少同步访问请求对象以及将其解压缩为二进制文件的方法数据。不幸的是,Django 通过将它们直接移动到内存或临时文件来处理上传,这不适用于我的用例。

有人建议我使用 gevent/greenlet 来处理上传,但我不确定这对等式有何影响,以及与 Django 一起需要什么设置才能使其正常工作。另外,在 Django 之外运行某些东西意味着我必须实现一个数据库连接层来验证是否允许上传(使用票证 ID)。

话虽如此,我该如何设置呢?Django 应该在 WSGI 应用程序中运行,并且有人还建议编写第二个 WSGI 应用程序来捕获用于上传的单个 URL 路径。我想尽可能多地利用 Django 框架,同时能够同步读取上传内容?

(我刚刚熟悉了requestsPython 库,不得不说我是一个非常忠实的粉丝,尽管我不知道在服务器上下文中使用它的第一件事。)

4

2 回答 2

5

我相信很多这些建议都过于复杂了。

您需要更改 Django 处理上传文件的方式吗?只需修改上传处理程序

相对简单,并为您提供了许多很棒的钩子。你应该能够扩展它来做你想做的事。

于 2013-03-04T20:14:12.347 回答
1

虽然我无法为您编写所有代码(这很复杂),但这是我推荐的设置。

  1. 使用 Tornado + Django:Tornado 可以嵌入 WSGI 进程,因此这使您能够让一个进程同时托管 Django 和这个 Tornado 处理程序。这是我的一个活动项目中的一个快速示例(尽管它使用 Tornado 作为 Socket.io 处理程序,但它应该为您提供解决方案的要点(:

    # Socket Server
    db = momoko.Pool(DB_DSN, **DB_CONFIG)
    router   = tornadio2.TornadioRouter(QueryRouter, user_settings={'db':db})
    sock_app = tornado.web.Application(router.urls, flash_policy_port = FL_PORT, flash_policy_file = path.join(PROJECT_ROOT, 'assets/xml/flashpolicy.xml'), socket_io_port = WS_PORT, debug=True)
    # Django Server
    os.environ['DJANGO_SETTINGS_MODULE'] = 'sever.settings'
    application = django.core.handlers.wsgi.WSGIHandler()
    container = tornado.wsgi.WSGIContainer(application)
    
    
    # Start the web servers
    if __name__ == "__main__":
        try:
            import logging
            tornado.options.parse_command_line()
            logging.getLogger().setLevel(logging.INFO)
            logging.info('Server started')
            tornado.locale.set_default_locale('us_US')
            http_server = tornado.httpserver.HTTPServer(container)
            http_server.listen(8000)
            tornadio2.SocketServer(sock_app, auto_start=True)
            tornado.ioloop.IOLoop.instance().start()
        except KeyboardInterrupt:
            tornado.ioloop.IOLoop.instance().stop()
            logging.info("Stopping servers.")
    

这可以很容易地转换为在两个不同端口上运行的两个服务器实例,其中 80 为 Django 保留,8080 用于您的上传处理程序。

  1. 我推荐 Tornado,因为它支持流式请求体,并且非常适合这种类型的使用。这是一个可能对您有所帮助的要点

  2. 您的代理设置很重要。如果您使用 NGINX,请确保关闭 proxy_buffering。

  3. 我不会使用数据库进行票证/上传检查。Redis 或 memcache 可能是处理此问题的更快方法。缓存也是在 Django 和 Tornado 之间来回上传进度的好方法,因为设置/获取新值的开销非常小。

这是一个棘手的大问题,需要严肃的工程才能提出一些优雅的东西,但它不仅仅是可行的。

于 2013-02-27T07:38:23.787 回答