|
12 | 12 | from django.conf import settings |
13 | 13 | from django.http import QueryDict |
14 | 14 | from django.http.multipartparser import parse_header |
| 15 | +from django.utils import six |
15 | 16 | from django.utils.datastructures import MultiValueDict |
16 | 17 | from django.utils.datastructures import MergeDict as DjangoMergeDict |
17 | | -from django.utils.six import BytesIO |
18 | 18 | from rest_framework import HTTP_HEADER_ENCODING |
19 | 19 | from rest_framework import exceptions |
20 | 20 | from rest_framework.settings import api_settings |
| 21 | +import sys |
21 | 22 | import warnings |
22 | 23 |
|
23 | 24 |
|
@@ -362,7 +363,7 @@ def _load_stream(self): |
362 | 363 | elif hasattr(self._request, 'read'): |
363 | 364 | self._stream = self._request |
364 | 365 | else: |
365 | | - self._stream = BytesIO(self.raw_post_data) |
| 366 | + self._stream = six.BytesIO(self.raw_post_data) |
366 | 367 |
|
367 | 368 | def _perform_form_overloading(self): |
368 | 369 | """ |
@@ -404,7 +405,7 @@ def _perform_form_overloading(self): |
404 | 405 | self._CONTENTTYPE_PARAM in self._data |
405 | 406 | ): |
406 | 407 | self._content_type = self._data[self._CONTENTTYPE_PARAM] |
407 | | - self._stream = BytesIO(self._data[self._CONTENT_PARAM].encode(self.parser_context['encoding'])) |
| 408 | + self._stream = six.BytesIO(self._data[self._CONTENT_PARAM].encode(self.parser_context['encoding'])) |
408 | 409 | self._data, self._files, self._full_data = (Empty, Empty, Empty) |
409 | 410 |
|
410 | 411 | def _parse(self): |
@@ -485,8 +486,16 @@ def _not_authenticated(self): |
485 | 486 | else: |
486 | 487 | self.auth = None |
487 | 488 |
|
488 | | - def __getattr__(self, attr): |
| 489 | + def __getattribute__(self, attr): |
489 | 490 | """ |
490 | | - Proxy other attributes to the underlying HttpRequest object. |
| 491 | + If an attribute does not exist on this instance, then we also attempt |
| 492 | + to proxy it to the underlying HttpRequest object. |
491 | 493 | """ |
492 | | - return getattr(self._request, attr) |
| 494 | + try: |
| 495 | + return super(Request, self).__getattribute__(attr) |
| 496 | + except AttributeError: |
| 497 | + info = sys.exc_info() |
| 498 | + try: |
| 499 | + return getattr(self._request, attr) |
| 500 | + except AttributeError: |
| 501 | + six.reraise(info[0], info[1], info[2].tb_next) |
0 commit comments