3

マルチパートファイルのアップロードをアップロード時にファイルのようなオブジェクトとして読み取るためのアクセス権が必要なDjangoアプリケーションがあります。つまり、リクエストオブジェクトへの多かれ少なかれ同期アクセスと、それをチャンクでバイナリに解凍する方法が必要です。データ。残念ながら、Djangoはアップロードをメモリまたは一時ファイルに直接移動することで処理しますが、これは私のユースケースでは機能しません。

アップロードを処理するためにgevent/greenletを使用することを勧めた人もいますが、それが方程式にどのように作用し、それを機能させるためにDjangoと一緒にどのような設定が必要かわかりません。さらに、Djangoの外部で何かを実行すると、アップロードが許可されていることを検証するためにデータベース接続レイヤーを実装する必要があります(チケットIDを使用)。

そうは言っても、どうすればこれを設定できますか?DjangoはWSGIアプリケーションで実行されている必要があり、アップロード用の単一のURLパスをキャプチャするために2番目のWSGIアプリケーションを作成することも推奨されていました。アップロードを同期的に読み取ることができる一方で、基本的にDjangoフレームワークを可能な限り活用したいですか?

(私はPythonライブラリに慣れたばかりでrequests、かなりの大ファンだと言わざるを得ませんが、サーバーコンテキストでの使用について最初に知ることはありません。)

4

2 に答える 2

5

これらの提案の多くは、物事を過度に複雑にしていると思います。

Django がアップロードされたファイルを処理する方法を変更する必要がありますか? アップロード ハンドラを変更するだけです。

基本クラスは比較的単純で、多くの優れたフックを提供します。あなたが望むことをするためにそれを拡張できるはずです。

于 2013-03-04T20:14:12.347 に答える
1

私はあなたのためにすべてのコードを書くことはできませんが(それは複雑です)、これが私の推奨されるセットアップです。

  1. Tornado + Djangoを使用する:TornadoはWSGIプロセスを埋め込むことができるため、単一のプロセスでDjangoとTornadoハンドラーの両方をホストすることができます。これが私のアクティブなプロジェクトの1つからの簡単なサンプルです(これは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.")
    

これは、2つの異なるポートで実行される2つのサーバーインスタンスに簡単に変換できます。80はDjango用に予約され、8080はアップロードハンドラー用に使用されます。

  1. ストリーミングリクエストボディをサポートし、このタイプの使用に非常に適しているため、トルネードをお勧めします。ここにあなたを助けるかもしれない要点があります

  2. プロキシの設定が重要になります。NGINXを使用している場合は、proxy_bufferingを必ずオフにしてください。

  3. チケット/アップロードのチェックにはデータベースを使用しません。Redisまたはmemcacheは、おそらくこれを処理するためのはるかに高速な方法です。新しい値を設定/取得するためのオーバーヘッドが非常に小さいため、キャッシュは、DjangoとTornadoの間でアップロードの進行状況を低音で切り替えるための優れた方法でもあります。

これは大きな厄介な問題であり、エンジニアリングがエレガントなものを思いつくことになるでしょうが、それは実行可能以上のものです。

于 2013-02-27T07:38:23.787 に答える