Ticket #20034: 1148.diff
File 1148.diff, 7.7 KB (added by , 12 years ago) |
---|
-
AUTHORS
diff --git a/AUTHORS b/AUTHORS index 4a9981d..2f91c08 100644
a b answer newbie questions, and generally made Django that much better: 293 293 Baurzhan Ismagulov <ibr@radix50.net> 294 294 Stephan Jaekel <steph@rdev.info> 295 295 james_027@yahoo.com 296 Tom Jaskowski <tadeck@gmail.com> 296 297 jcrasta@gmail.com 297 298 jdetaeye 298 299 Dmitry Jemerov <intelliyole@gmail.com> -
django/core/files/uploadhandler.py
diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index f5e95cf..49ed98d 100644
a b def file_complete(self, file_size): 113 113 """ 114 114 raise NotImplementedError() 115 115 116 def variable_complete(self, variable_name, variable_value): 117 """ 118 Signal that a new variable has been parsed from the multipart request. 119 120 :param variable_name: name of the variable 121 :param variable_value: value of the multipart variable 122 """ 123 pass 124 116 125 def upload_complete(self): 117 126 """ 118 127 Signal that the upload is complete. Subclasses should perform cleanup -
django/http/multipartparser.py
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 26e10da..6679899 100644
a b def parse(self): 167 167 else: 168 168 data = field_stream.read() 169 169 170 self._post.appendlist(field_name, 171 force_text(data, encoding, errors='replace')) 170 field_text = force_text(data, encoding, errors='replace') 171 self._post.appendlist(field_name, field_text) 172 173 for handler in handlers: 174 try: 175 handler.variable_complete(field_name, field_text) 176 except StopFutureHandlers: 177 break 178 172 179 elif item_type == FILE: 173 180 # This is a file, use the handler... 174 181 file_name = disposition.get('filename') -
docs/topics/http/file-uploads.txt
diff --git a/docs/topics/http/file-uploads.txt b/docs/topics/http/file-uploads.txt index 80bd5f3..aa857af 100644
a b attributes: 425 425 ``FileUploadHandler.upload_complete(self)`` 426 426 Callback signaling that the entire upload (all files) has completed. 427 427 428 ``FileUploadHandler.variable_complete(self, variable_name, variable_value)`` 429 Callback signaling that a new variable has been parsed. This is called 430 before new file is parsed. 431 432 ``variable_name`` is a string name of the non-file ``<input>`` field. 433 434 ``variable_value`` is the value (text) provided in the field by browser. 435 436 This method may raise a ``StopFutureHandlers`` exception to prevent 437 future handlers from handling this variable. 438 439 .. versionadded:: 1.6 440 441 The ``variable_complete`` method was added in Django 1.6. 442 428 443 ``FileUploadHandler.handle_raw_input(self, input_data, META, content_length, boundary, encoding)`` 429 444 Allows the handler to completely override the parsing of the raw 430 445 HTTP input. -
tests/requests/tests.py
diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 676cd05..8e76832 100644
a b 1 1 # -*- encoding: utf-8 -*- 2 2 from __future__ import unicode_literals 3 3 4 from contextlib import contextmanager 4 5 import time 5 6 import warnings 6 7 from datetime import datetime, timedelta … … def read(self, len=0): 659 660 with self.assertRaises(UnreadablePostError): 660 661 request.body 661 662 663 def test_POST_new_variable_signal_in_multipart(self): 664 """ 665 Multi part POST requests should allow reading variables even before 666 parsing whole files. This can be done by overloading file upload 667 handlers' ``new_variable`` method. 668 """ 669 collected_variables_memory_handler = [] 670 collected_variables_temporary_handler = [] 671 672 def get_var_collector(handler): 673 """Retrieve variable collector for specific handler""" 674 def _collect_variable(self, variable_name, variable_value): 675 """Store variable in external list, to check it later""" 676 if handler == 'memory': 677 collected_variables_memory_handler.append( 678 (variable_name, variable_value), 679 ) 680 elif handler == 'temporary': 681 collected_variables_temporary_handler.append( 682 (variable_name, variable_value), 683 ) 684 else: 685 raise NotImplementedError( 686 'Collector for %s not implemented' % (handler,), 687 ) 688 return _collect_variable 689 690 @contextmanager 691 def override_upload_handler_methods(): 692 """Override parser method temporarily""" 693 from django.core.files.uploadhandler import ( 694 MemoryFileUploadHandler, TemporaryFileUploadHandler, 695 ) 696 old_method_memory = MemoryFileUploadHandler.variable_complete 697 old_method_temporary = TemporaryFileUploadHandler.variable_complete 698 699 # Override handler method: 700 MemoryFileUploadHandler.variable_complete = get_var_collector( 701 'memory', 702 ) 703 TemporaryFileUploadHandler.variable_complete = get_var_collector( 704 'temporary', 705 ) 706 yield 707 # Recover previous state: 708 MemoryFileUploadHandler.new_variable = old_method_memory 709 TemporaryFileUploadHandler.new_variable = old_method_temporary 710 711 payload = FakePayload( 712 "\r\n".join([ 713 '--boundary', 714 'Content-Disposition: form-data; name="n1"', 715 '', 716 'value', 717 '--boundary', 718 'Content-Disposition: form-data; name="n2"; filename="f.txt"', 719 'Content-Type: text/plain', 720 '', 721 '... contents of file1.txt ...', 722 'value', 723 '--boundary--', 724 'Content-Disposition: form-data; name="n3"', 725 '', 726 'value', 727 '--boundary--', 728 ''])) 729 request = WSGIRequest({ 730 'REQUEST_METHOD': 'POST', 731 'CONTENT_TYPE': 'multipart/form-data; boundary=boundary', 732 'CONTENT_LENGTH': len(payload), 733 'wsgi.input': payload}) 734 735 # Use specific upload handlers 736 upload_handlers = ( 737 'django.core.files.uploadhandler.MemoryFileUploadHandler', 738 'django.core.files.uploadhandler.TemporaryFileUploadHandler', 739 ) 740 with override_upload_handler_methods(), self.settings( 741 FILE_UPLOAD_HANDLERS=upload_handlers, 742 ): 743 self.assertEqual( 744 request.POST, 745 { 746 'n1': ['value'], 747 'n3': ['value'], 748 }, 749 ) 750 self.assertEqual(len(request.FILES), 1) 751 self.assertIn('n2', request.FILES) 752 753 # Confirm the variables have been collected: 754 self.assertEqual( 755 collected_variables_memory_handler, 756 [('n1', 'value'), ('n3', 'value')], 757 ) 758 self.assertEqual( 759 collected_variables_temporary_handler, 760 [('n1', 'value'), ('n3', 'value')], 761 ) 762 662 763 663 764 @skipIf(connection.vendor == 'sqlite' 664 765 and connection.settings_dict['NAME'] in ('', ':memory:'),