Fixed #23911 -- Added support for buffer file uploads in the test client
This commit is contained in:
parent
dc2d75f4d4
commit
018d110ef5
1
AUTHORS
1
AUTHORS
|
@ -650,6 +650,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Thomas Sorrel
|
Thomas Sorrel
|
||||||
Thomas Steinacher <http://www.eggdrop.ch/>
|
Thomas Steinacher <http://www.eggdrop.ch/>
|
||||||
Thomas Stromberg <tstromberg@google.com>
|
Thomas Stromberg <tstromberg@google.com>
|
||||||
|
Thomas Tanner <tanner@gmx.net>
|
||||||
tibimicu@gmx.net
|
tibimicu@gmx.net
|
||||||
Tim Graham <timograham@gmail.com>
|
Tim Graham <timograham@gmail.com>
|
||||||
Tim Heap <tim@timheap.me>
|
Tim Heap <tim@timheap.me>
|
||||||
|
|
|
@ -195,20 +195,25 @@ def encode_multipart(boundary, data):
|
||||||
|
|
||||||
def encode_file(boundary, key, file):
|
def encode_file(boundary, key, file):
|
||||||
to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET)
|
to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET)
|
||||||
|
filename = os.path.basename(file.name) if hasattr(file, 'name') else ''
|
||||||
if hasattr(file, 'content_type'):
|
if hasattr(file, 'content_type'):
|
||||||
content_type = file.content_type
|
content_type = file.content_type
|
||||||
|
elif filename:
|
||||||
|
content_type = mimetypes.guess_type(filename)[0]
|
||||||
else:
|
else:
|
||||||
content_type = mimetypes.guess_type(file.name)[0]
|
content_type = None
|
||||||
|
|
||||||
if content_type is None:
|
if content_type is None:
|
||||||
content_type = 'application/octet-stream'
|
content_type = 'application/octet-stream'
|
||||||
|
if not filename:
|
||||||
|
filename = key
|
||||||
return [
|
return [
|
||||||
to_bytes('--%s' % boundary),
|
to_bytes('--%s' % boundary),
|
||||||
to_bytes('Content-Disposition: form-data; name="%s"; filename="%s"'
|
to_bytes('Content-Disposition: form-data; name="%s"; filename="%s"'
|
||||||
% (key, os.path.basename(file.name))),
|
% (key, filename)),
|
||||||
to_bytes('Content-Type: %s' % content_type),
|
to_bytes('Content-Type: %s' % content_type),
|
||||||
b'',
|
b'',
|
||||||
file.read()
|
to_bytes(file.read())
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -511,6 +511,8 @@ Tests
|
||||||
:meth:`TestCase.setUpTestData() <django.test.TestCase.setUpTestData>`. Using
|
:meth:`TestCase.setUpTestData() <django.test.TestCase.setUpTestData>`. Using
|
||||||
this technique can speed up the tests as compared to using ``setUp()``.
|
this technique can speed up the tests as compared to using ``setUp()``.
|
||||||
|
|
||||||
|
* Added test client support for file uploads with file-like objects.
|
||||||
|
|
||||||
Validators
|
Validators
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -238,6 +238,13 @@ Use the ``django.test.Client`` class to make requests.
|
||||||
(The name ``attachment`` here is not relevant; use whatever name your
|
(The name ``attachment`` here is not relevant; use whatever name your
|
||||||
file-processing code expects.)
|
file-processing code expects.)
|
||||||
|
|
||||||
|
You may also provide any file-like object (e.g., :class:`~io.StringIO` or
|
||||||
|
:class:`~io.BytesIO`) as a file handle.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
The ability to use a file-like object was added.
|
||||||
|
|
||||||
Note that if you wish to use the same file handle for multiple
|
Note that if you wish to use the same file handle for multiple
|
||||||
``post()`` calls then you will need to manually reset the file
|
``post()`` calls then you will need to manually reset the file
|
||||||
pointer between posts. The easiest way to do this is to
|
pointer between posts. The easiest way to do this is to
|
||||||
|
|
|
@ -17,7 +17,7 @@ from django.test import TestCase, client
|
||||||
from django.test import override_settings
|
from django.test import override_settings
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
from django.utils.http import urlquote
|
from django.utils.http import urlquote
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import BytesIO, StringIO
|
||||||
|
|
||||||
from . import uploadhandler
|
from . import uploadhandler
|
||||||
from .models import FileModel
|
from .models import FileModel
|
||||||
|
@ -262,6 +262,34 @@ class FileUploadTests(TestCase):
|
||||||
self.assertLess(len(got), 256,
|
self.assertLess(len(got), 256,
|
||||||
"Got a long file name (%s characters)." % len(got))
|
"Got a long file name (%s characters)." % len(got))
|
||||||
|
|
||||||
|
def test_file_content(self):
|
||||||
|
tdir = tempfile.gettempdir()
|
||||||
|
|
||||||
|
file = tempfile.NamedTemporaryFile
|
||||||
|
with file(suffix=".ctype_extra", dir=tdir) as no_content_type, \
|
||||||
|
file(suffix=".ctype_extra", dir=tdir) as simple_file:
|
||||||
|
no_content_type.write(b'no content')
|
||||||
|
no_content_type.seek(0)
|
||||||
|
|
||||||
|
simple_file.write(b'text content')
|
||||||
|
simple_file.seek(0)
|
||||||
|
simple_file.content_type = 'text/plain'
|
||||||
|
|
||||||
|
string_io = StringIO('string content')
|
||||||
|
bytes_io = BytesIO(b'binary content')
|
||||||
|
|
||||||
|
response = self.client.post('/echo_content/', {
|
||||||
|
'no_content_type': no_content_type,
|
||||||
|
'simple_file': simple_file,
|
||||||
|
'string': string_io,
|
||||||
|
'binary': bytes_io,
|
||||||
|
})
|
||||||
|
received = json.loads(response.content.decode('utf-8'))
|
||||||
|
self.assertEqual(received['no_content_type'], 'no content')
|
||||||
|
self.assertEqual(received['simple_file'], 'text content')
|
||||||
|
self.assertEqual(received['string'], 'string content')
|
||||||
|
self.assertEqual(received['binary'], 'binary content')
|
||||||
|
|
||||||
def test_content_type_extra(self):
|
def test_content_type_extra(self):
|
||||||
"""Uploaded files may have content type parameters available."""
|
"""Uploaded files may have content type parameters available."""
|
||||||
tdir = tempfile.gettempdir()
|
tdir = tempfile.gettempdir()
|
||||||
|
|
Loading…
Reference in New Issue