I am trying to specify a specific method of handling file uploads for a class based view. Per the docs this can be achieved by something like:
from django.core.files.uploadhandler import TemporaryFileUploadHandler
request.upload_handlers = [TemporaryFileUploadHandler(request=request)]
If i specify this in post
method of a FormView
like so:
def post(self, request, *args, **kwargs):
request.upload_handlers = [TemporaryFileUploadHandler(request=request)]
return super().post(self, request, *args, **kwargs)
I get:
AttributeError: You cannot set the upload handlers after the upload has been processed.
Variants like yield the same result:
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)
However when i do this in the get
method this is ineffective:
def get(self, request, *args, **kwargs):
request.upload_handlers = [TemporaryFileUploadHandler(request=self.request)]
return super().get(self, request, *args, **kwargs)
If I upload a small file it still uses the default django.core.files.uploadhandler.MemoryFileUploadHandler
.
What am I doing wrong?
Also when i try to mirror what is suggested in the note, I get the same AttributeError
:
from django.views.decorators.csrf import csrf_exempt, csrf_protect
@csrf_exempt
def post(self, request, *args, **kwargs):
request.upload_handlers = [TemporaryFileUploadHandler(request=request)]
return self._post(request, *args, **kwargs)
@csrf_protect
def _post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
Ok, finally got it to work (using the suggestions provided by @Alasdair). Setting a method decorator(crsf_exempt)
on post
is not engough it needs to be on dispatch
. For anyone struggling with this in the future, it goes like this:
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)
Also it will fail if you remove the {% csrf_token %}
from your template (which is what you want).