Hi, I'm having issues with my unit-testing on file uploads.
I have the following unit-test using the APIClient provided by APITestCase:
@override_settings(MEDIA_ROOT='/tmp/django_test')
def test_attach_file_to_deed(self):
self._require_login()
response = self.client.post(
'/api/deeds/%s/attach_file/' % (self.test_deed.pk, ),
{
'file': self.dummyfile,
},
)
self.assertqual(response.status_code, status.HTTP_201_CREATED, 'Error on create.')
But it fails to populate the request.FILES['file'] in the view and gives me the following error:
django.utils.datastructures.MultiValueDictKeyError: "'file'"
My view looks like this:
@action()
def attach_file(self, request, pk=None):
deed = self.get_object()
serializer = AttachmentSerializer(
data={
'parent': deed.pk,
'file': request.FILES['file'],
'original_filename': request.FILES['file'].name,
},
)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I could really use a little help debugging this one.
Files should be populated with the files argument to serializers, not the data argument. Hope that helps!
For future reference, using the files parameter in the serializer and setting my APIClient request to format='multipart' fixed all my issues.
@w00kie Can I have a look at your Serializer? I'm facing similar issues.
My view
def post(self, request, aid, format='multipart'):
'''
Upload New Image
'''
business = SomeModel.objects.get(aid=aid)
serialiser = PictureSerialiser(data={'business': business}, files=request.FILES['image'])
if serialiser.is_valid():
serialiser.save()
return Response(serialiser.data, status=status.HTTP_201_CREATED)
return Response(serialiser.errors, status=status.HTTP_400_BAD_REQUEST)
My test:
def test_upload_photo(self):
c = Client()
test_file = 'path/to/image'
with open(test_file, 'rb') as data:
response = c.post(''some_url", {'image': data}, **self.oauth_header)
self.assertEqual(response.status_code, 201)
Hi,
I would like to test the request.FILES
my view looks like this:
@login_required
def upload(request, model_id):
if not request.POST or not request.FILES:
return HttpResponseRedirect(reverse('model_detail', args=(model_id,)))
...
I have used this in a previous test to test that a model have a file:
from django.core.files.base import File
...
def test(self):
with File(file=tempfile.NamedTemporaryFile()) as f:
...
Thanks,
I know that's an old thread, but I just encountered similar error, I didn't use file serializer though. So, to whom face this issue, there is a solution. To make it work use from django.core.files.uploadedfile import SimpleUploadedFile:
# this is pytest
def test_request_multipart(self, mocker, api_client, video):
video_upload = SimpleUploadedFile("file.webm", video, content_type="video/webm")
data = {
'video_file': video_upload
}
response = api_client.post(self.endpoint_url, data, format='multipart')
passing format='multipart' argument resolves the error
response = api_client.post(self.endpoint_url, data, format='multipart')
Most helpful comment
I know that's an old thread, but I just encountered similar error, I didn't use file serializer though. So, to whom face this issue, there is a solution. To make it work use
from django.core.files.uploadedfile import SimpleUploadedFile: