1

ファイルアップロードの進行状況のフィードバックを提供するには、特定のビューのカスタムアップロードハンドラーをインストールする必要があります。これは、次の「古典的な」Djangoビューについて文書化されています。

https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#modifying-upload-handlers-on-the-fly

ただし、一般的なビューの場合、手順が見つからなかったため、次のことを思いつきました。

from django.utils import importlib
from django.core.exceptions import ImproperlyConfigured
from django.views.decorators.csrf import csrf_protect

class UploadHandlerMixin(object):
    '''
        A mixin for Django generic views that installs a custom upload handler in front of
        the current chain of upload handlers.

        You specify the handler to install by overriding the 'upload_handler' attribute of
        the class, specifying the module and class name in the form 'path.to.module.class':

            class MyView(UploadHandlerMixin, View):
                upload_handler = 'path.to.module.MyUploadHandler'

        If you do not override 'upload_handler', no additional upload handler will be
        installed.

        If the CsrfViewMiddleware is installed (which is the default) then you must use
        your view as follows in your urls.py:

            from django.views.decorators.csrf import csrf_exempt
            url(r'^.../$', csrf_exempt(MyView.as_view()), ...),

        Internally, the UploadHandlerMixin mixin will install the upload handler and then
        perform the CSRF check. (This is necessary because the CSRF check inspects
        request.POST, and afterwards upload handlers cannot be changed, see documentation
        link given below.)

        The handler is installed as described in the Django documentation "Modifying upload handlers
        on the fly", see https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#modifying-upload-handlers-on-the-fly
    '''

    upload_handler = None

    def dispatch(self, request, *args, **kwargs):
        if not self.upload_handler is None:
            request.upload_handlers.insert(0, UploadHandlerMixin._instantiate_upload_handler(self.upload_handler, request))
        return _uploadhandler_dispatch(request, self, *args, **kwargs)

    @staticmethod
    def _instantiate_upload_handler(path, *args, **kwargs):
        i = path.rfind('.')
        module, attr = path[:i], path[i+1:]
        try:
            mod = importlib.import_module(module)
        except ImportError, e:
            raise ImproperlyConfigured('Error importing upload handler module %s: "%s"' % (module, e))
        except ValueError, e:
            raise ImproperlyConfigured('Error importing upload handler module. Is FILE_UPLOAD_HANDLERS a correctly defined list or tuple?')
        try:
            cls = getattr(mod, attr)
        except AttributeError:
            raise ImproperlyConfigured('Module "%s" does not define a "%s" upload handler backend' % (module, attr))
        return cls(*args, **kwargs)

@csrf_protect
def _uploadhandler_dispatch(request, view, *args, **kwargs):
    return super(UploadHandlerMixin, view).dispatch(request, *args, **kwargs)

これは、タスクを実行するための「推奨される方法」ですか?セキュリティ面では大丈夫ですか?

4

1 に答える 1

0

自分自身に答えると、サービス側のソリューション(カスタムアップロードハンドラーを備えたDjangoなど)の代わりに、JQueryFileUploadのようなクライアント側のソリューションがあります。最近のブラウザでは、アップロードの進行状況をクライアントで読み取ることができるという事実を利用しています。私の場合、これは実装がはるかに簡単で、追加のサーバー負荷は発生しません。

于 2011-11-15T16:31:02.197 に答える