diff --git a/rest_framework/request.py b/rest_framework/request.py index ffbe4a367..6f4269fe5 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -250,6 +250,10 @@ class Request(object): else: self._full_data = self._data + # copy files refs to the underlying request so that closable + # objects are handled appropriately. + self._request._files = self._files + def _load_stream(self): """ Return the content body of the request, as a stream. diff --git a/tests/test_fields.py b/tests/test_fields.py index 47dd274e8..38dc5f7a7 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1144,7 +1144,7 @@ class TestDateTimeField(FieldValues): valid_inputs = { '2001-01-01 13:00': datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc), '2001-01-01T13:00': datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc), - '2001-01-01T13:00Z': datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc) + '2001-01-01T13:00Z': datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc), datetime.datetime(2001, 1, 1, 13, 00): datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc), datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc): datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc), } diff --git a/tests/test_request.py b/tests/test_request.py index 428b969f5..208d2737e 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -3,6 +3,9 @@ Tests for content parsing, and form-overloaded content parsing. """ from __future__ import unicode_literals +import os.path +import tempfile + from django.conf.urls import url from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User @@ -120,11 +123,39 @@ class MockView(APIView): return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +class FileUploadView(APIView): + def post(self, request): + filenames = [file.temporary_file_path() for file in request.FILES.values()] + + for filename in filenames: + assert os.path.exists(filename) + + return Response(status=status.HTTP_200_OK, data=filenames) + + urlpatterns = [ url(r'^$', MockView.as_view()), + url(r'^upload/$', FileUploadView.as_view()) ] +@override_settings( + ROOT_URLCONF='tests.test_request', + FILE_UPLOAD_HANDLERS=['django.core.files.uploadhandler.TemporaryFileUploadHandler']) +class FileUploadTests(TestCase): + + def test_fileuploads_closed_at_request_end(self): + with tempfile.NamedTemporaryFile() as f: + response = self.client.post('/upload/', {'file': f}) + + # sanity check that file was processed + assert len(response.data) == 1 + + for file in response.data: + assert not os.path.exists(file) + + @override_settings(ROOT_URLCONF='tests.test_request') class TestContentParsingWithAuthentication(TestCase): def setUp(self):