Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #7651: uploading multiple files with the same name now work. Al…

…so, in order to test the problem the test client now handles uploading multiple files at once. Patch from Mike Axiak.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@7858 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 9dabd1f8ff7760f28bd1dcfa8b83ae6b1c0b79aa 1 parent 7254495
@jacobian jacobian authored
View
1  django/http/multipartparser.py
@@ -136,6 +136,7 @@ def parse(self):
# since we cannot be sure a file is complete until
# we hit the next boundary/part of the multipart content.
self.handle_file_complete(old_field_name, counters)
+ old_field_name = None
try:
disposition = meta_data['content-disposition'][1]
View
51 django/test/client.py
@@ -90,32 +90,34 @@ def encode_multipart(boundary, data):
"""
lines = []
to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
+
+ # Not by any means perfect, but good enough for our purposes.
+ is_file = lambda thing: hasattr(thing, "read") and callable(thing.read)
+
+ # Each bit of the multipart form data could be either a form value or a
+ # file, or a *list* of form values and/or files. Remember that HTTP field
+ # names can be duplicated!
for (key, value) in data.items():
- if isinstance(value, file):
- lines.extend([
- '--' + boundary,
- 'Content-Disposition: form-data; name="%s"; filename="%s"' \
- % (to_str(key), to_str(os.path.basename(value.name))),
- 'Content-Type: application/octet-stream',
- '',
- value.read()
- ])
- else:
- if not isinstance(value, basestring) and is_iterable(value):
- for item in value:
+ if is_file(value):
+ lines.extend(encode_file(boundary, key, value))
+ elif not isinstance(value, basestring) and is_iterable(value):
+ for item in value:
+ if is_file(item):
+ lines.extend(encode_file(boundary, key, item))
+ else:
lines.extend([
'--' + boundary,
'Content-Disposition: form-data; name="%s"' % to_str(key),
'',
to_str(item)
])
- else:
- lines.extend([
- '--' + boundary,
- 'Content-Disposition: form-data; name="%s"' % to_str(key),
- '',
- to_str(value)
- ])
+ else:
+ lines.extend([
+ '--' + boundary,
+ 'Content-Disposition: form-data; name="%s"' % to_str(key),
+ '',
+ to_str(value)
+ ])
lines.extend([
'--' + boundary + '--',
@@ -123,6 +125,17 @@ def encode_multipart(boundary, data):
])
return '\r\n'.join(lines)
+def encode_file(boundary, key, file):
+ to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
+ return [
+ '--' + boundary,
+ 'Content-Disposition: form-data; name="%s"; filename="%s"' \
+ % (to_str(key), to_str(os.path.basename(file.name))),
+ 'Content-Type: application/octet-stream',
+ '',
+ file.read()
+ ]
+
class Client:
"""
A class that can act as a client for testing purposes.
View
31 tests/regressiontests/file_uploads/tests.py
@@ -147,12 +147,35 @@ def test_custom_upload_handler(self):
def test_broken_custom_upload_handler(self):
f = tempfile.NamedTemporaryFile()
f.write('a' * (2 ** 21))
-
+
# AttributeError: You cannot alter upload handlers after the upload has been processed.
self.assertRaises(
AttributeError,
self.client.post,
- '/file_uploads/quota/broken/',
+ '/file_uploads/quota/broken/',
{'f': open(f.name)}
- )
-
+ )
+
+ def test_fileupload_getlist(self):
+ file1 = tempfile.NamedTemporaryFile()
+ file1.write('a' * (2 ** 23))
+
+ file2 = tempfile.NamedTemporaryFile()
+ file2.write('a' * (2 * 2 ** 18))
+
+ file2a = tempfile.NamedTemporaryFile()
+ file2a.write('a' * (5 * 2 ** 20))
+
+ response = self.client.post('/file_uploads/getlist_count/', {
+ 'file1': open(file1.name),
+ 'field1': u'test',
+ 'field2': u'test3',
+ 'field3': u'test5',
+ 'field4': u'test6',
+ 'field5': u'test7',
+ 'file2': (open(file2.name), open(file2a.name))
+ })
+ got = simplejson.loads(response.content)
+
+ self.assertEqual(got.get('file1'), 1)
+ self.assertEqual(got.get('file2'), 2)
View
1  tests/regressiontests/file_uploads/urls.py
@@ -7,4 +7,5 @@
(r'^echo/$', views.file_upload_echo),
(r'^quota/$', views.file_upload_quota),
(r'^quota/broken/$', views.file_upload_quota_broken),
+ (r'^getlist_count/$', views.file_upload_getlist_count),
)
View
12 tests/regressiontests/file_uploads/views.py
@@ -67,4 +67,14 @@ def file_upload_quota_broken(request):
"""
response = file_upload_echo(request)
request.upload_handlers.insert(0, QuotaUploadHandler())
- return response
+ return response
+
+def file_upload_getlist_count(request):
+ """
+ Check the .getlist() function to ensure we receive the correct number of files.
+ """
+ file_counts = {}
+
+ for key in request.FILES.keys():
+ file_counts[key] = len(request.FILES.getlist(key))
+ return HttpResponse(simplejson.dumps(file_counts))
Please sign in to comment.
Something went wrong with that request. Please try again.