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

File rename-raw_post_data-to-body-updated2.diff, 16.2 KB (added by Donald Stufft, 12 years ago)

Removed Duplicate Tests + Added A Test to Verify raw_post_data == 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/internals/deprecation.txt

    diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
    index 91fde96..9fcb681 100644
    a b these changes.  
    257257* Setting the ``is_safe`` and ``needs_autoescape`` flags as attributes of
    258258  template filter functions will no longer be supported.
    259259
     260* The attribute ``HttpRequest.raw_post_data`` was renamed to ``HttpRequest.body``
     261  in 1.4. The backwards compatibility shim will be removed.
     262
    2602632.0
    261264---
    262265
  • docs/ref/request-response.txt

    diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
    index 64d0e10..8c2b7a6 100644
    a b Attributes  
    3030
    3131All attributes except ``session`` should be considered read-only.
    3232
     33.. attribute:: HttpRequest.body
     34
     35    .. versionchanged:: 1.4
     36      Prior to 1.4, ``HttpRequest.body`` was named ``HttpRequest.raw_post_data``.
     37
     38    The raw HTTP request body as a byte string. This is useful for processing
     39    data in different formats than of conventional HTML forms: binary images,
     40    XML payload etc. For processing form data use ``HttpRequest.POST``.
     41
     42    .. versionadded:: 1.3
     43
     44    You can also read from an HttpRequest using file-like interface. See
     45    :meth:`HttpRequest.read()`.
     46
    3347.. attribute:: HttpRequest.path
    3448
    3549    A string representing the full path to the requested page, not including
    All attributes except ``session`` should be considered read-only.  
    170184    support activated. See the :doc:`session documentation
    171185    </topics/http/sessions>` for full details.
    172186
    173 .. attribute:: HttpRequest.raw_post_data
    174 
    175     The raw HTTP POST data as a byte string. This is useful for processing
    176     data in different formats than of conventional HTML forms: binary images,
    177     XML payload etc. For processing form data use ``HttpRequest.POST``.
    178 
    179     .. versionadded:: 1.3
    180 
    181     You can also read from an HttpRequest using file-like interface. See
    182     :meth:`HttpRequest.read()`.
    183 
    184187.. attribute:: HttpRequest.urlconf
    185188
    186189    Not defined by Django itself, but will be read if other code (e.g., a custom
  • docs/releases/1.4.txt

    diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt
    index f614dee..385010b 100644
    a b useful, it was removed in Django 1.4. If you relied on it, you must edit your  
    995995settings file to list all your applications explicitly.
    996996
    997997.. _this can't be done reliably: http://docs.python.org/tutorial/modules.html#importing-from-a-package
     998
     999``HttpRequest.raw_post_data renamed to HttpRequest.body``
     1000~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1001This attribute was named ``HttpRequest.raw_post_data`` but what it actually provided
     1002was the body of the HTTP request. It has been renamed to ``HttpRequest.body`` to
     1003better match what it actually provides and ``HttpRequest.raw_post_data`` has been
     1004deprecated.
  • 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..7927d27 100644
    a b  
    11import time
     2import warnings
    23from datetime import datetime, timedelta
    34from StringIO import StringIO
    45
     
    67from django.core.handlers.modpython import ModPythonRequest
    78from django.core.handlers.wsgi import WSGIRequest, LimitedStream
    89from django.http import HttpRequest, HttpResponse, parse_cookie, build_request_repr
     10from django.test.utils import get_warnings_state, restore_warnings_state
    911from django.utils import unittest
    1012from django.utils.http import cookie_date
    1113
    def test_stream(self):  
    294296    def test_read_after_value(self):
    295297        """
    296298        Reading from request is allowed after accessing request contents as
    297         POST or raw_post_data.
     299        POST or body.
    298300        """
    299301        payload = 'name=value'
    300302        request = WSGIRequest({'REQUEST_METHOD': 'POST',
    301303                               'CONTENT_LENGTH': len(payload),
    302304                               'wsgi.input': StringIO(payload)})
    303305        self.assertEqual(request.POST, {u'name': [u'value']})
    304         self.assertEqual(request.raw_post_data, 'name=value')
     306        self.assertEqual(request.body, 'name=value')
    305307        self.assertEqual(request.read(), 'name=value')
    306308
    307309    def test_value_after_read(self):
    308310        """
    309         Construction of POST or raw_post_data is not allowed after reading
     311        Construction of POST or body is not allowed after reading
    310312        from request.
    311313        """
    312314        payload = 'name=value'
    def test_value_after_read(self):  
    314316                               'CONTENT_LENGTH': len(payload),
    315317                               'wsgi.input': StringIO(payload)})
    316318        self.assertEqual(request.read(2), 'na')
    317         self.assertRaises(Exception, lambda: request.raw_post_data)
     319        self.assertRaises(Exception, lambda: request.body)
    318320        self.assertEqual(request.POST, {})
    319321
    320     def test_raw_post_data_after_POST_multipart(self):
     322    def test_body_after_POST_multipart(self):
    321323        """
    322         Reading raw_post_data after parsing multipart is not allowed
     324        Reading body after parsing multipart is not allowed
    323325        """
    324326        # Because multipart is used for large amounts fo data i.e. file uploads,
    325327        # 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.
     328        # silence the error by setting body = '' either.
    327329        payload = "\r\n".join([
    328330                '--boundary',
    329331                'Content-Disposition: form-data; name="name"',
    def test_raw_post_data_after_POST_multipart(self):  
    336338                               'CONTENT_LENGTH': len(payload),
    337339                               'wsgi.input': StringIO(payload)})
    338340        self.assertEqual(request.POST, {u'name': [u'value']})
    339         self.assertRaises(Exception, lambda: request.raw_post_data)
     341        self.assertRaises(Exception, lambda: request.body)
    340342
    341343    def test_POST_multipart_with_content_length_zero(self):
    342344        """
    def test_read_by_lines(self):  
    366368                               'wsgi.input': StringIO(payload)})
    367369        self.assertEqual(list(request), ['name=value'])
    368370
    369     def test_POST_after_raw_post_data_read(self):
     371    def test_POST_after_body_read(self):
    370372        """
    371         POST should be populated even if raw_post_data is read first
     373        POST should be populated even if body is read first
    372374        """
    373375        payload = 'name=value'
    374376        request = WSGIRequest({'REQUEST_METHOD': 'POST',
    375377                               'CONTENT_LENGTH': len(payload),
    376378                               'wsgi.input': StringIO(payload)})
    377         raw_data = request.raw_post_data
     379        raw_data = request.body
    378380        self.assertEqual(request.POST, {u'name': [u'value']})
    379381
    380     def test_POST_after_raw_post_data_read_and_stream_read(self):
     382    def test_POST_after_body_read_and_stream_read(self):
    381383        """
    382         POST should be populated even if raw_post_data is read first, and then
     384        POST should be populated even if body is read first, and then
    383385        the stream is read second.
    384386        """
    385387        payload = 'name=value'
    386388        request = WSGIRequest({'REQUEST_METHOD': 'POST',
    387389                               'CONTENT_LENGTH': len(payload),
    388390                               'wsgi.input': StringIO(payload)})
    389         raw_data = request.raw_post_data
     391        raw_data = request.body
    390392        self.assertEqual(request.read(1), u'n')
    391393        self.assertEqual(request.POST, {u'name': [u'value']})
    392394
    393     def test_POST_after_raw_post_data_read_and_stream_read_multipart(self):
     395    def test_POST_after_body_read_and_stream_read_multipart(self):
    394396        """
    395         POST should be populated even if raw_post_data is read first, and then
     397        POST should be populated even if body is read first, and then
    396398        the stream is read second. Using multipart/form-data instead of urlencoded.
    397399        """
    398400        payload = "\r\n".join([
    def test_POST_after_raw_post_data_read_and_stream_read_multipart(self):  
    406408                               'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
    407409                               'CONTENT_LENGTH': len(payload),
    408410                               'wsgi.input': StringIO(payload)})
    409         raw_data = request.raw_post_data
     411        raw_data = request.body
    410412        # Consume enough data to mess up the parsing:
    411413        self.assertEqual(request.read(13), u'--boundary\r\nC')
    412414        self.assertEqual(request.POST, {u'name': [u'value']})
     415
     416    def test_raw_post_data_returns_body(self):
     417        """
     418        HttpRequest.raw_post_body should be the same as HttpRequest.body
     419        """
     420        payload = 'Hello There!'
     421        request = WSGIRequest({
     422            'REQUEST_METHOD': 'POST',
     423            'CONTENT_LENGTH': len(payload),
     424            'wsgi.input': StringIO(payload)
     425        })
     426
     427        warnings_state = get_warnings_state()
     428        warnings.filterwarnings('ignore', category=DeprecationWarning, module='django.http')
     429        self.assertEqual(request.body, request.raw_post_data)
     430        restore_warnings_state(warnings_state)
  • 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..4ddd957 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.read() and
    979979    HttpRequest.read(BUFFER) have proper LimitedStream behaviour.
    980980
    981981    Refs #14753, #15785
    982982    """
    983     def test_raw_post_data_from_empty_request(self):
    984         """HttpRequest.raw_post_data on a test client GET request should return
     983
     984    def test_body_from_empty_request(self):
     985        """HttpRequest.body 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        self.assertEquals(self.client.get("/test_client_regress/body/").content, '')
    987988
    988989    def test_read_from_empty_request(self):
    989990        """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..d869c23 100644
    a b  
    3131    (r'^parse_unicode_json/$', views.return_json_file),
    3232    (r'^check_headers/$', views.check_headers),
    3333    (r'^check_headers_redirect/$', RedirectView.as_view(url='/test_client_regress/check_headers/')),
    34     (r'^raw_post_data/$', views.raw_post_data),
     34    (r'^body/$', views.body),
    3535    (r'^read_all/$', views.read_all),
    3636    (r'^read_buffer/$', views.read_buffer),
    3737    (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..ebb68c4 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):  
    9294    "A view that responds with value of the X-ARG-CHECK header"
    9395    return HttpResponse('HTTP_X_ARG_CHECK: %s' % request.META.get('HTTP_X_ARG_CHECK', 'Undefined'))
    9496
    95 def raw_post_data(request):
    96     "A view that is requested with GET and accesses request.raw_post_data. Refs #14753."
    97     return HttpResponse(request.raw_post_data)
     97def body(request):
     98    "A view that is requested with GET and accesses request.body. Refs #14753."
     99    return HttpResponse(request.body)
    98100
    99101def read_all(request):
    100102    "A view that is requested with accesses request.read()."
Back to Top