在哪里/如何替换Django CBV中的默认上传处理程序?

时间:2017-11-22 15:25:12

标签: python django django-forms django-file-upload

我正在尝试为基于类的视图指定处理文件上载的特定方法。根据{{​​3}},这可以通过以下方式实现:

from django.core.files.uploadhandler import TemporaryFileUploadHandler
request.upload_handlers = [TemporaryFileUploadHandler(request=request)]

如果我在post的{​​{1}}方法中指定此项,请执行以下操作:

FormView

我明白了:

def post(self, request, *args, **kwargs):
    request.upload_handlers = [TemporaryFileUploadHandler(request=request)]
    return super().post(self,  request, *args, **kwargs)

变体会产生相同的结果:

AttributeError: You cannot set the upload handlers after the upload has been processed.

但是当我在def post(self, request, *args, **kwargs): self.request.upload_handlers = [TemporaryFileUploadHandler(request=self.request)] form = self.get_form() if form.is_valid(): return self.form_valid(form) else: return self.form_invalid(form) 方法中执行此操作时,这是无效的:

get

如果我上传一个小文件,它仍会使用默认的 def get(self, request, *args, **kwargs): request.upload_handlers = [TemporaryFileUploadHandler(request=self.request)] return super().get(self, request, *args, **kwargs)

我做错了什么?

编辑

此外,当我尝试镜像docs中建议的内容时,我得到相同的django.core.files.uploadhandler.MemoryFileUploadHandler

AttributeError

2 个答案:

答案 0 :(得分:2)

因为您无法在视图中更改上传处理程序,因为它是在您的视图函数之前调用的内容。

获取不应该收集帖子参数,因此它的行为也相应。

  

Upload Handlers

     

当用户上传文件时,Django会将文件数据传递给   上传处理程序 - 一个处理文件数据的小类   上传。上传处理程序最初定义在   FILE_UPLOAD_HANDLERS设置,默认为:

 ["django.core.files.uploadhandler.MemoryFileUploadHandler",
 "django.core.files.uploadhandler.TemporaryFileUploadHandler"]

如果您想要不同的上传处理程序,可以更改FILE_UPLOAD_HANDLERS设置

如果这还不够,您可以写下custom upload handler

编辑:

  

此外,启用了fromrrViewViewMiddleware访问request.POST   默认情况下。这意味着您需要在视图上使用csrf_exempt()   允许您更改上传处理程序。

答案 1 :(得分:2)

好的,终于让它工作了(使用@Alasdair提供的建议)。在method decorator(crsf_exempt)上设置post并非需要dispatch。对于任何在未来苦苦挣扎的人来说,就像这样:

from django.views.generic import FormView
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt, csrf_protect


@method_decorator(csrf_exempt, 'dispatch')
class UploadDataSetView(FormView):

    def post(self, request, *args, **kwargs):
        request.upload_handlers = [TemporaryFileUploadHandler(request=request)]  
        return self._post(request)

    @method_decorator(csrf_protect)
    def _post(self, request):
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

如果您从模板中移除{% csrf_token %}(这是您想要的),它也会失败。