我正在尝试为基于类的视图指定处理文件上载的特定方法。根据{{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
答案 0 :(得分:2)
因为您无法在视图中更改上传处理程序,因为它是在您的视图函数之前调用的内容。
获取不应该收集帖子参数,因此它的行为也相应。
当用户上传文件时,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 %}
(这是您想要的),它也会失败。