Ticket #17323: rename-raw_post_data-to-body.diff

File rename-raw_post_data-to-body.diff, 19.0 KB (added by Donald Stufft, 13 years ago)

Rename raw_post_data to body

  • django/http/__init__.py

    diff --git a/django/http/__init__.py b/django/http/__init__.py
    index 476a625..bb1c3b6 100644
    a b  
    44import os
    55import re
    66import time
     7import warnings
     8
    79from pprint import pformat
    810from urllib import urlencode, quote
    911from urlparse import urljoin
    def parse_file_upload(self, META, post_data):  
    300302        parser = MultiPartParser(META, post_data, self.upload_handlers, self.encoding)
    301303        return parser.parse()
    302304
    303     def _get_raw_post_data(self):
    304         if not hasattr(self, '_raw_post_data'):
     305    @property
     306    def body(self):
     307        if not hasattr(self, '_body'):
    305308            if self._read_started:
    306                 raise Exception("You cannot access raw_post_data after reading from request's data stream")
    307             self._raw_post_data = self.read()
    308             self._stream = StringIO(self._raw_post_data)
    309         return self._raw_post_data
    310     raw_post_data = property(_get_raw_post_data)
     309                raise Exception("You cannot access body after reading from request's data stream")
     310            self._body = self.read()
     311            self._stream = StringIO(self._body)
     312        return self._body
     313
     314    @property
     315    def raw_post_data(self):
     316        warnings.warn(
     317        'The raw_post_data attribute has been renamed to body and the original '
     318        'name has been deprecated.', PendingDeprecationWarning)
     319        return self.body
    311320
    312321    def _mark_post_parse_error(self):
    313322        self._post = QueryDict('')
    def _load_post_and_files(self):  
    319328        if self.method != 'POST':
    320329            self._post, self._files = QueryDict('', encoding=self._encoding), MultiValueDict()
    321330            return
    322         if self._read_started and not hasattr(self, '_raw_post_data'):
     331        if self._read_started and not hasattr(self, '_body'):
    323332            self._mark_post_parse_error()
    324333            return
    325334
    326335        if self.META.get('CONTENT_TYPE', '').startswith('multipart'):
    327             if hasattr(self, '_raw_post_data'):
     336            if hasattr(self, '_body'):
    328337                # Use already read data
    329                 data = StringIO(self._raw_post_data)
     338                data = StringIO(self._body)
    330339            else:
    331340                data = self
    332341            try:
    def _load_post_and_files(self):  
    342351                self._mark_post_parse_error()
    343352                raise
    344353        else:
    345             self._post, self._files = QueryDict(self.raw_post_data, encoding=self._encoding), MultiValueDict()
     354            self._post, self._files = QueryDict(self.body, encoding=self._encoding), MultiValueDict()
    346355
    347356    ## File-like and iterator interface.
    348357    ##
    349358    ## Expects self._stream to be set to an appropriate source of bytes by
    350359    ## a corresponding request subclass (WSGIRequest or ModPythonRequest).
    351360    ## Also when request data has already been read by request.POST or
    352     ## request.raw_post_data, self._stream points to a StringIO instance
     361    ## request.body, self._stream points to a StringIO instance
    353362    ## containing that data.
    354363
    355364    def read(self, *args, **kwargs):
  • docs/ref/request-response.txt

    diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
    index 64d0e10..b6fffb2 100644
    a b Attributes  
    3030
    3131All attributes except ``session`` should be considered read-only.
    3232
     33.. attribute:: HttpRequest.body
     34
     35    .. versionadded:: 1.4
     36
     37    The raw HTTP request body as a byte string. This is useful for processing
     38    data in different formats than of conventional HTML forms: binary images,
     39    XML payload etc. For processing form data use ``HttpRequest.POST``.
     40
     41    .. versionadded:: 1.3
     42
     43    You can also read from an HttpRequest using file-like interface. See
     44    :meth:`HttpRequest.read()`.
     45
    3346.. attribute:: HttpRequest.path
    3447
    3548    A string representing the full path to the requested page, not including
    All attributes except ``session`` should be considered read-only.  
    172185
    173186.. attribute:: HttpRequest.raw_post_data
    174187
     188    .. deprecated:: 1.4
     189
    175190    The raw HTTP POST data as a byte string. This is useful for processing
    176191    data in different formats than of conventional HTML forms: binary images,
    177192    XML payload etc. For processing form data use ``HttpRequest.POST``.
  • tests/modeltests/test_client/views.py

    diff --git a/tests/modeltests/test_client/views.py b/tests/modeltests/test_client/views.py
    index a86064e..6ea7213 100644
    a b def raw_post_view(request):  
    4444    """A view which expects raw XML to be posted and returns content extracted
    4545    from the XML"""
    4646    if request.method == 'POST':
    47         root = parseString(request.raw_post_data)
     47        root = parseString(request.body)
    4848        first_book = root.firstChild.firstChild
    4949        title, author = [n.firstChild.nodeValue for n in first_book.childNodes]
    5050        t = Template("{{ title }} - {{ author }}", name="Book template")
  • tests/regressiontests/requests/tests.py

    diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py
    index e96f312..a3bfea0 100644
    a b  
    11import time
     2import warnings
    23from datetime import datetime, timedelta
    34from StringIO import StringIO
    45
    def test_stream(self):  
    291292                               'wsgi.input': StringIO(payload)})
    292293        self.assertEqual(request.read(), 'name=value')
    293294
    294     def test_read_after_value(self):
     295    def test_read_after_value_raw_post_data(self):
    295296        """
    296297        Reading from request is allowed after accessing request contents as
    297298        POST or raw_post_data.
    298299        """
     300        with warnings.catch_warnings():
     301            warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     302            warnings.filterwarnings("ignore", category=DeprecationWarning)
     303
     304            payload = 'name=value'
     305            request = WSGIRequest({'REQUEST_METHOD': 'POST',
     306                                   'CONTENT_LENGTH': len(payload),
     307                                   'wsgi.input': StringIO(payload)})
     308            self.assertEqual(request.POST, {u'name': [u'value']})
     309            self.assertEqual(request.raw_post_data, 'name=value')
     310            self.assertEqual(request.read(), 'name=value')
     311
     312    def test_read_after_value(self):
     313        """
     314        Reading from request is allowed after accessing request contents as
     315        POST or body.
     316        """
    299317        payload = 'name=value'
    300318        request = WSGIRequest({'REQUEST_METHOD': 'POST',
    301319                               'CONTENT_LENGTH': len(payload),
    302320                               'wsgi.input': StringIO(payload)})
    303321        self.assertEqual(request.POST, {u'name': [u'value']})
    304         self.assertEqual(request.raw_post_data, 'name=value')
     322        self.assertEqual(request.body, 'name=value')
    305323        self.assertEqual(request.read(), 'name=value')
    306324
    307     def test_value_after_read(self):
     325    def test_value_after_read_raw_post_data(self):
    308326        """
    309327        Construction of POST or raw_post_data is not allowed after reading
    310328        from request.
    311329        """
     330        with warnings.catch_warnings():
     331            warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     332            warnings.filterwarnings("ignore", category=DeprecationWarning)
     333
     334            payload = 'name=value'
     335            request = WSGIRequest({'REQUEST_METHOD': 'POST',
     336                                   'CONTENT_LENGTH': len(payload),
     337                                   'wsgi.input': StringIO(payload)})
     338            self.assertEqual(request.read(2), 'na')
     339            self.assertRaises(Exception, lambda: request.raw_post_data)
     340            self.assertEqual(request.POST, {})
     341
     342    def test_value_after_read(self):
     343        """
     344        Construction of POST or body is not allowed after reading
     345        from request.
     346        """
    312347        payload = 'name=value'
    313348        request = WSGIRequest({'REQUEST_METHOD': 'POST',
    314349                               'CONTENT_LENGTH': len(payload),
    315350                               'wsgi.input': StringIO(payload)})
    316351        self.assertEqual(request.read(2), 'na')
    317         self.assertRaises(Exception, lambda: request.raw_post_data)
     352        self.assertRaises(Exception, lambda: request.body)
    318353        self.assertEqual(request.POST, {})
    319354
    320355    def test_raw_post_data_after_POST_multipart(self):
    321356        """
    322357        Reading raw_post_data after parsing multipart is not allowed
    323358        """
     359        with warnings.catch_warnings():
     360            warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     361            warnings.filterwarnings("ignore", category=DeprecationWarning)
     362
     363            # Because multipart is used for large amounts fo data i.e. file uploads,
     364            # we don't want the data held in memory twice, and we don't want to
     365            # silence the error by setting raw_post_data = '' either.
     366            payload = "\r\n".join([
     367                    '--boundary',
     368                    'Content-Disposition: form-data; name="name"',
     369                    '',
     370                    'value',
     371                    '--boundary--'
     372                    ''])
     373            request = WSGIRequest({'REQUEST_METHOD': 'POST',
     374                                   'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
     375                                   'CONTENT_LENGTH': len(payload),
     376                                   'wsgi.input': StringIO(payload)})
     377            self.assertEqual(request.POST, {u'name': [u'value']})
     378            self.assertRaises(Exception, lambda: request.raw_post_data)
     379
     380    def test_body_after_POST_multipart(self):
     381        """
     382        Reading body after parsing multipart is not allowed
     383        """
    324384        # Because multipart is used for large amounts fo data i.e. file uploads,
    325385        # we don't want the data held in memory twice, and we don't want to
    326         # silence the error by setting raw_post_data = '' either.
     386        # silence the error by setting body = '' either.
    327387        payload = "\r\n".join([
    328388                '--boundary',
    329389                'Content-Disposition: form-data; name="name"',
    def test_raw_post_data_after_POST_multipart(self):  
    336396                               'CONTENT_LENGTH': len(payload),
    337397                               'wsgi.input': StringIO(payload)})
    338398        self.assertEqual(request.POST, {u'name': [u'value']})
    339         self.assertRaises(Exception, lambda: request.raw_post_data)
     399        self.assertRaises(Exception, lambda: request.body)
    340400
    341401    def test_POST_multipart_with_content_length_zero(self):
    342402        """
    def test_POST_after_raw_post_data_read(self):  
    370430        """
    371431        POST should be populated even if raw_post_data is read first
    372432        """
     433        with warnings.catch_warnings():
     434            warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     435            warnings.filterwarnings("ignore", category=DeprecationWarning)
     436
     437            payload = 'name=value'
     438            request = WSGIRequest({'REQUEST_METHOD': 'POST',
     439                                   'CONTENT_LENGTH': len(payload),
     440                                   'wsgi.input': StringIO(payload)})
     441            raw_data = request.raw_post_data
     442            self.assertEqual(request.POST, {u'name': [u'value']})
     443
     444    def test_POST_after_body_read(self):
     445        """
     446        POST should be populated even if body is read first
     447        """
    373448        payload = 'name=value'
    374449        request = WSGIRequest({'REQUEST_METHOD': 'POST',
    375450                               'CONTENT_LENGTH': len(payload),
    376451                               'wsgi.input': StringIO(payload)})
    377         raw_data = request.raw_post_data
     452        raw_data = request.body
    378453        self.assertEqual(request.POST, {u'name': [u'value']})
    379454
    380455    def test_POST_after_raw_post_data_read_and_stream_read(self):
    def test_POST_after_raw_post_data_read_and_stream_read(self):  
    382457        POST should be populated even if raw_post_data is read first, and then
    383458        the stream is read second.
    384459        """
     460        with warnings.catch_warnings():
     461            warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     462            warnings.filterwarnings("ignore", category=DeprecationWarning)
     463
     464            payload = 'name=value'
     465            request = WSGIRequest({'REQUEST_METHOD': 'POST',
     466                                   'CONTENT_LENGTH': len(payload),
     467                                   'wsgi.input': StringIO(payload)})
     468            raw_data = request.raw_post_data
     469            self.assertEqual(request.read(1), u'n')
     470            self.assertEqual(request.POST, {u'name': [u'value']})
     471
     472    def test_POST_after_body_read_and_stream_read(self):
     473        """
     474        POST should be populated even if body is read first, and then
     475        the stream is read second.
     476        """
    385477        payload = 'name=value'
    386478        request = WSGIRequest({'REQUEST_METHOD': 'POST',
    387479                               'CONTENT_LENGTH': len(payload),
    388480                               'wsgi.input': StringIO(payload)})
    389         raw_data = request.raw_post_data
     481        raw_data = request.body
    390482        self.assertEqual(request.read(1), u'n')
    391483        self.assertEqual(request.POST, {u'name': [u'value']})
    392484
    def test_POST_after_raw_post_data_read_and_stream_read_multipart(self):  
    395487        POST should be populated even if raw_post_data is read first, and then
    396488        the stream is read second. Using multipart/form-data instead of urlencoded.
    397489        """
     490        with warnings.catch_warnings():
     491            warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     492            warnings.filterwarnings("ignore", category=DeprecationWarning)
     493
     494            payload = "\r\n".join([
     495                    '--boundary',
     496                    'Content-Disposition: form-data; name="name"',
     497                    '',
     498                    'value',
     499                    '--boundary--'
     500                    ''])
     501            request = WSGIRequest({'REQUEST_METHOD': 'POST',
     502                                   'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
     503                                   'CONTENT_LENGTH': len(payload),
     504                                   'wsgi.input': StringIO(payload)})
     505            raw_data = request.raw_post_data
     506            # Consume enough data to mess up the parsing:
     507            self.assertEqual(request.read(13), u'--boundary\r\nC')
     508            self.assertEqual(request.POST, {u'name': [u'value']})
     509
     510    def test_POST_after_body_read_and_stream_read_multipart(self):
     511        """
     512        POST should be populated even if body is read first, and then
     513        the stream is read second. Using multipart/form-data instead of urlencoded.
     514        """
    398515        payload = "\r\n".join([
    399516                '--boundary',
    400517                'Content-Disposition: form-data; name="name"',
    def test_POST_after_raw_post_data_read_and_stream_read_multipart(self):  
    406523                               'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
    407524                               'CONTENT_LENGTH': len(payload),
    408525                               'wsgi.input': StringIO(payload)})
    409         raw_data = request.raw_post_data
     526        raw_data = request.body
    410527        # Consume enough data to mess up the parsing:
    411528        self.assertEqual(request.read(13), u'--boundary\r\nC')
    412529        self.assertEqual(request.POST, {u'name': [u'value']})
  • tests/regressiontests/test_client_regress/models.py

    diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py
    index 7d0b0e4..160cfa6 100644
    a b def test_response_no_template(self):  
    975975
    976976class ReadLimitedStreamTest(TestCase):
    977977    """
    978     Tests that ensure that HttpRequest.raw_post_data, HttpRequest.read() and
     978    Tests that ensure that HttpRequest.body, HttpRequest.raw_post_data, HttpRequest.read() and
    979979    HttpRequest.read(BUFFER) have proper LimitedStream behaviour.
    980980
    981981    Refs #14753, #15785
    982982    """
     983
    983984    def test_raw_post_data_from_empty_request(self):
    984985        """HttpRequest.raw_post_data on a test client GET request should return
    985986        the empty string."""
    986         self.assertEquals(self.client.get("/test_client_regress/raw_post_data/").content, '')
     987        with warnings.catch_warnings():
     988            warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     989            warnings.filterwarnings("ignore", category=DeprecationWarning)
     990
     991            self.assertEquals(self.client.get("/test_client_regress/raw_post_data/").content, '')
     992
     993    def test_body_from_empty_request(self):
     994        """HttpRequest.body on a test client GET request should return
     995        the empty string."""
     996        self.assertEquals(self.client.get("/test_client_regress/body/").content, '')
    987997
    988998    def test_read_from_empty_request(self):
    989999        """HttpRequest.read() on a test client GET request should return the
  • tests/regressiontests/test_client_regress/urls.py

    diff --git a/tests/regressiontests/test_client_regress/urls.py b/tests/regressiontests/test_client_regress/urls.py
    index 93f7a2e..db3c9de 100644
    a b  
    3232    (r'^check_headers/$', views.check_headers),
    3333    (r'^check_headers_redirect/$', RedirectView.as_view(url='/test_client_regress/check_headers/')),
    3434    (r'^raw_post_data/$', views.raw_post_data),
     35    (r'^body/$', views.body),
    3536    (r'^read_all/$', views.read_all),
    3637    (r'^read_buffer/$', views.read_buffer),
    3738    (r'^request_context_view/$', views.request_context_view),
  • tests/regressiontests/test_client_regress/views.py

    diff --git a/tests/regressiontests/test_client_regress/views.py b/tests/regressiontests/test_client_regress/views.py
    index b398293..21c700c 100644
    a b  
     1import warnings
     2
    13from django.conf import settings
    24from django.contrib.auth.decorators import login_required
    35from django.http import HttpResponse, HttpResponseRedirect
    def return_json_file(request):  
    7981        charset = settings.DEFAULT_CHARSET
    8082
    8183    # This just checks that the uploaded data is JSON
    82     obj_dict = simplejson.loads(request.raw_post_data.decode(charset))
     84    obj_dict = simplejson.loads(request.body.decode(charset))
    8385    obj_json = simplejson.dumps(obj_dict, encoding=charset,
    8486                                cls=DjangoJSONEncoder,
    8587                                ensure_ascii=False)
    def check_headers(request):  
    9496
    9597def raw_post_data(request):
    9698    "A view that is requested with GET and accesses request.raw_post_data. Refs #14753."
    97     return HttpResponse(request.raw_post_data)
     99    with warnings.catch_warnings():
     100        warnings.filterwarnings("ignore", category=PendingDeprecationWarning)
     101        warnings.filterwarnings("ignore", category=DeprecationWarning)
     102
     103        return HttpResponse(request.raw_post_data)
     104
     105def body(request):
     106    "A view that is requested with GET and accesses request.body. Refs #14753."
     107    return HttpResponse(request.body)
    98108
    99109def read_all(request):
    100110    "A view that is requested with accesses request.read()."
Back to Top