为了提供文件上传的进度反馈,我需要为特定视图安装自定义上传处理程序。这是在
的“经典”Django视图中记录的https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#modifying-upload-handlers-on-the-fly
然而,对于generic views,我找不到任何说明,我想出了以下内容:
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)
这是完成任务的“推荐方式”吗?安全方面可以吗?
答案 0 :(得分:0)
回答自己,服务端解决方案的替代方案(如带有自定义上传处理程序的Django)是像JQuery File Upload这样的客户端解决方案。它使用了更新的浏览器允许在客户端上读取上载进度的事实。在我的例子中,这实现起来要简单得多,并且不会导致额外的服务器负载。