diff options
| author | Tom Christie | 2014-12-03 23:24:06 +0000 | 
|---|---|---|
| committer | Tom Christie | 2014-12-03 23:24:06 +0000 | 
| commit | 3d6620c72a9cbaedecc37cc76e591a79409de305 (patch) | |
| tree | ee3b2a12ee552daac3a49862ae2fc6e934975b34 | |
| parent | cd4d8660211e7af3b06986b68a9281be0b8ffacf (diff) | |
| parent | 731c8421afe3093a78cdabb9c3cc28fa52cd1c8e (diff) | |
| download | django-rest-framework-3d6620c72a9cbaedecc37cc76e591a79409de305.tar.bz2 | |
Merge
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | docs/api-guide/parsers.md | 22 | ||||
| -rw-r--r-- | docs/api-guide/renderers.md | 42 | ||||
| -rw-r--r-- | docs/api-guide/settings.md | 4 | ||||
| -rw-r--r-- | docs/api-guide/testing.md | 4 | ||||
| -rw-r--r-- | docs/index.md | 2 | ||||
| -rw-r--r-- | docs/tutorial/2-requests-and-responses.md | 2 | ||||
| -rw-r--r-- | requirements-test.txt | 4 | ||||
| -rw-r--r-- | rest_framework/compat.py | 7 | ||||
| -rw-r--r-- | rest_framework/parsers.py | 25 | ||||
| -rw-r--r-- | rest_framework/renderers.py | 25 | ||||
| -rw-r--r-- | rest_framework/settings.py | 4 | ||||
| -rw-r--r-- | rest_framework/utils/encoders.py | 65 | ||||
| -rw-r--r-- | tests/test_renderers.py | 53 | ||||
| -rw-r--r-- | tests/test_templatetags.py | 13 | ||||
| -rw-r--r-- | tox.ini | 1 | 
16 files changed, 28 insertions, 246 deletions
| @@ -214,6 +214,5 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  [docs]: http://www.django-rest-framework.org/  [urlobject]: https://github.com/zacharyvoase/urlobject  [markdown]: http://pypi.python.org/pypi/Markdown/ -[pyyaml]: http://pypi.python.org/pypi/PyYAML  [django-filter]: http://pypi.python.org/pypi/django-filter  [security-mail]: mailto:rest-framework-security@googlegroups.com diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index 32819146..9323d382 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -26,26 +26,26 @@ As an example, if you are sending `json` encoded data using jQuery with the [.aj  ## Setting the parsers -The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSES` setting.  For example, the following settings would allow requests with `YAML` content. +The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSES` setting.  For example, the following settings would allow requests with `JSON` content.      REST_FRAMEWORK = {          'DEFAULT_PARSER_CLASSES': ( -            'rest_framework.parsers.YAMLParser', +            'rest_framework.parsers.JSONParser',          )      }  You can also set the parsers used for an individual view, or viewset,  using the `APIView` class based views. -	from rest_framework.parsers import YAMLParser +	from rest_framework.parsers import JSONParser  	from rest_framework.response import Response      from rest_framework.views import APIView      class ExampleView(APIView):          """ -        A view that can accept POST requests with YAML content. +        A view that can accept POST requests with JSON content.          """ -        parser_classes = (YAMLParser,) +        parser_classes = (JSONParser,)          def post(self, request, format=None):              return Response({'received data': request.data}) @@ -53,10 +53,10 @@ using the `APIView` class based views.  Or, if you're using the `@api_view` decorator with function based views.      @api_view(['POST']) -    @parser_classes((YAMLParser,)) +    @parser_classes((JSONParser,))      def example_view(request, format=None):          """ -        A view that can accept POST requests with YAML content. +        A view that can accept POST requests with JSON content.          """          return Response({'received data': request.data}) @@ -70,14 +70,6 @@ Parses `JSON` request content.  **.media_type**: `application/json` -## YAMLParser - -Parses `YAML` request content. - -Requires the `pyyaml` package to be installed. - -**.media_type**: `application/yaml` -  ## FormParser  Parses HTML form content.  `request.data` will be populated with a `QueryDict` of data. diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index 1490eef6..69460dbc 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -18,11 +18,11 @@ For more information see the documentation on [content negotiation][conneg].  ## Setting the renderers -The default set of renderers may be set globally, using the `DEFAULT_RENDERER_CLASSES` setting.  For example, the following settings would use `YAML` as the main media type and also include the self describing API. +The default set of renderers may be set globally, using the `DEFAULT_RENDERER_CLASSES` setting.  For example, the following settings would use `JSON` as the main media type and also include the self describing API.      REST_FRAMEWORK = {          'DEFAULT_RENDERER_CLASSES': ( -            'rest_framework.renderers.YAMLRenderer', +            'rest_framework.renderers.JSONRenderer',              'rest_framework.renderers.BrowsableAPIRenderer',          )      } @@ -31,15 +31,15 @@ You can also set the renderers used for an individual view, or viewset,  using the `APIView` class based views.      from django.contrib.auth.models import User -    from rest_framework.renderers import JSONRenderer, YAMLRenderer +    from rest_framework.renderers import JSONRenderer      from rest_framework.response import Response      from rest_framework.views import APIView      class UserCountView(APIView):          """ -        A view that returns the count of active users, in JSON or YAML. +        A view that returns the count of active users in JSON.          """ -        renderer_classes = (JSONRenderer, YAMLRenderer) +        renderer_classes = (JSONRenderer, )          def get(self, request, format=None):              user_count = User.objects.filter(active=True).count() @@ -93,38 +93,6 @@ The default JSON encoding style can be altered using the `UNICODE_JSON` and `COM  **.charset**: `None` -## YAMLRenderer - -Renders the request data into `YAML`. - -Requires the `pyyaml` package to be installed. - -Note that non-ascii characters will be rendered using `\uXXXX` character escape.  For example: - -    unicode black star: "\u2605" - -**.media_type**: `application/yaml` - -**.format**: `'.yaml'` - -**.charset**: `utf-8` - -## UnicodeYAMLRenderer - -Renders the request data into `YAML`. - -Requires the `pyyaml` package to be installed. - -Note that non-ascii characters will not be character escaped.  For example: - -    unicode black star: ★ - -**.media_type**: `application/yaml` - -**.format**: `'.yaml'` - -**.charset**: `utf-8` -  ## TemplateHTMLRenderer  Renders data to HTML, using Django's standard template rendering. diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 9005511b..623d89fb 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -12,10 +12,10 @@ For example your project's `settings.py` file might include something like this:      REST_FRAMEWORK = {          'DEFAULT_RENDERER_CLASSES': ( -            'rest_framework.renderers.YAMLRenderer', +            'rest_framework.renderers.JSONRenderer',          ),          'DEFAULT_PARSER_CLASSES': ( -            'rest_framework.parsers.YAMLParser', +            'rest_framework.parsers.JSONParser',          )      } diff --git a/docs/api-guide/testing.md b/docs/api-guide/testing.md index d059fdab..cd8c7820 100644 --- a/docs/api-guide/testing.md +++ b/docs/api-guide/testing.md @@ -255,14 +255,14 @@ The default format used to make test requests may be set using the `TEST_REQUEST  If you need to test requests using something other than multipart or json requests, you can do so by setting the `TEST_REQUEST_RENDERER_CLASSES` setting. -For example, to add support for using `format='yaml'` in test requests, you might have something like this in your `settings.py` file. +For example, to add support for using `format='html'` in test requests, you might have something like this in your `settings.py` file.      REST_FRAMEWORK = {          ...          'TEST_REQUEST_RENDERER_CLASSES': (              'rest_framework.renderers.MultiPartRenderer',              'rest_framework.renderers.JSONRenderer', -            'rest_framework.renderers.YAMLRenderer' +            'rest_framework.renderers.TemplateHTMLRenderer'          )      } diff --git a/docs/index.md b/docs/index.md index ac5d5a01..136f344e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -54,7 +54,6 @@ REST framework requires the following:  The following packages are optional:  * [Markdown][markdown] (2.1.0+) - Markdown support for the browsable API. -* [PyYAML][yaml] (3.10+) - YAML content-type support.  * [django-filter][django-filter] (0.5.4+) - Filtering support.  * [django-restframework-oauth][django-restframework-oauth] package for OAuth 1.0a and 2.0 support.  * [django-guardian][django-guardian] (1.1.1+) - Object level permissions support. @@ -254,7 +253,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  [mozilla]: http://www.mozilla.org/en-US/about/  [eventbrite]: https://www.eventbrite.co.uk/about/  [markdown]: http://pypi.python.org/pypi/Markdown/ -[yaml]: http://pypi.python.org/pypi/PyYAML  [django-filter]: http://pypi.python.org/pypi/django-filter  [django-restframework-oauth]: https://github.com/jlafon/django-rest-framework-oauth  [django-guardian]: https://github.com/lukaszb/django-guardian diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index f377c712..06a684b1 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -92,7 +92,7 @@ Here is the view for an individual snippet, in the `views.py` module.  This should all feel very familiar - it is not a lot different from working with regular Django views. -Notice that we're no longer explicitly tying our requests or responses to a given content type.  `request.data` can handle incoming `json` requests, but it can also handle `yaml` and other formats.  Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us. +Notice that we're no longer explicitly tying our requests or responses to a given content type.  `request.data` can handle incoming `json` requests, but it can also handle other formats.  Similarly we're returning response objects with data, but allowing REST framework to render the response into the correct content type for us.  ## Adding optional format suffixes to our URLs diff --git a/requirements-test.txt b/requirements-test.txt index 2fb859da..eae43ae2 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -6,7 +6,11 @@ flake8==2.2.2  # Optional packages  markdown>=2.1.0 +<<<<<<< HEAD  PyYAML>=3.10 +======= +defusedxml>=0.3 +>>>>>>> 731c8421afe3093a78cdabb9c3cc28fa52cd1c8e  django-guardian==1.2.4  django-filter>=0.5.4  Pillow==2.3.0 diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 06da3770..08dd9df6 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -237,13 +237,6 @@ except ImportError:      apply_markdown = None -# Yaml is optional -try: -    import yaml -except ImportError: -    yaml = None - -  # `seperators` argument to `json.dumps()` differs between 2.x and 3.x  # See: http://bugs.python.org/issue22767  if six.PY3: diff --git a/rest_framework/parsers.py b/rest_framework/parsers.py index 6d0e932b..1960e5a8 100644 --- a/rest_framework/parsers.py +++ b/rest_framework/parsers.py @@ -12,7 +12,7 @@ from django.http import QueryDict  from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser  from django.http.multipartparser import MultiPartParserError, parse_header, ChunkIter  from django.utils import six -from rest_framework.compat import yaml, force_text, urlparse +from rest_framework.compat import force_text, urlparse  from rest_framework.exceptions import ParseError  from rest_framework import renderers  import json @@ -63,29 +63,6 @@ class JSONParser(BaseParser):              raise ParseError('JSON parse error - %s' % six.text_type(exc)) -class YAMLParser(BaseParser): -    """ -    Parses YAML-serialized data. -    """ - -    media_type = 'application/yaml' - -    def parse(self, stream, media_type=None, parser_context=None): -        """ -        Parses the incoming bytestream as YAML and returns the resulting data. -        """ -        assert yaml, 'YAMLParser requires pyyaml to be installed' - -        parser_context = parser_context or {} -        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) - -        try: -            data = stream.read().decode(encoding) -            return yaml.safe_load(data) -        except (ValueError, yaml.parser.ParserError) as exc: -            raise ParseError('YAML parse error - %s' % six.text_type(exc)) - -  class FormParser(BaseParser):      """      Parser for form data. diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index e8caa40f..173e48dc 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -17,7 +17,7 @@ from django.template import Context, RequestContext, loader, Template  from django.test.client import encode_multipart  from django.utils import six  from rest_framework import exceptions, serializers, status, VERSION -from rest_framework.compat import SHORT_SEPARATORS, LONG_SEPARATORS, yaml +from rest_framework.compat import SHORT_SEPARATORS, LONG_SEPARATORS  from rest_framework.exceptions import ParseError  from rest_framework.settings import api_settings  from rest_framework.request import is_form_media_type, override_method @@ -103,29 +103,6 @@ class JSONRenderer(BaseRenderer):          return ret -class YAMLRenderer(BaseRenderer): -    """ -    Renderer which serializes to YAML. -    """ - -    media_type = 'application/yaml' -    format = 'yaml' -    encoder = encoders.SafeDumper -    charset = 'utf-8' -    ensure_ascii = False - -    def render(self, data, accepted_media_type=None, renderer_context=None): -        """ -        Renders `data` into serialized YAML. -        """ -        assert yaml, 'YAMLRenderer requires pyyaml to be installed' - -        if data is None: -            return '' - -        return yaml.dump(data, stream=None, encoding=self.charset, Dumper=self.encoder, allow_unicode=not self.ensure_ascii) - -  class TemplateHTMLRenderer(BaseRenderer):      """      An HTML renderer for use with templates. diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 1e8c27fc..3abc1fe8 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -5,11 +5,11 @@ For example your project's `settings.py` file might look like this:  REST_FRAMEWORK = {      'DEFAULT_RENDERER_CLASSES': (          'rest_framework.renderers.JSONRenderer', -        'rest_framework.renderers.YAMLRenderer', +        'rest_framework.renderers.TemplateHTMLRenderer',      )      'DEFAULT_PARSER_CLASSES': (          'rest_framework.parsers.JSONParser', -        'rest_framework.parsers.YAMLParser', +        'rest_framework.parsers.TemplateHTMLRenderer',      )  } diff --git a/rest_framework/utils/encoders.py b/rest_framework/utils/encoders.py index 4d6bb3a3..2c97f1d7 100644 --- a/rest_framework/utils/encoders.py +++ b/rest_framework/utils/encoders.py @@ -5,10 +5,9 @@ from __future__ import unicode_literals  from django.db.models.query import QuerySet  from django.utils import six, timezone  from django.utils.functional import Promise -from rest_framework.compat import force_text, OrderedDict +from rest_framework.compat import force_text  import datetime  import decimal -import types  import json @@ -56,65 +55,3 @@ class JSONEncoder(json.JSONEncoder):          elif hasattr(obj, '__iter__'):              return tuple(item for item in obj)          return super(JSONEncoder, self).default(obj) - - -try: -    import yaml -except ImportError: -    SafeDumper = None -else: -    # Adapted from http://pyyaml.org/attachment/ticket/161/use_ordered_dict.py -    class SafeDumper(yaml.SafeDumper): -        """ -        Handles decimals as strings. -        Handles OrderedDicts as usual dicts, but preserves field order, rather -        than the usual behaviour of sorting the keys. -        """ -        def represent_decimal(self, data): -            return self.represent_scalar('tag:yaml.org,2002:str', six.text_type(data)) - -        def represent_mapping(self, tag, mapping, flow_style=None): -            value = [] -            node = yaml.MappingNode(tag, value, flow_style=flow_style) -            if self.alias_key is not None: -                self.represented_objects[self.alias_key] = node -            best_style = True -            if hasattr(mapping, 'items'): -                mapping = list(mapping.items()) -                if not isinstance(mapping, OrderedDict): -                    mapping.sort() -            for item_key, item_value in mapping: -                node_key = self.represent_data(item_key) -                node_value = self.represent_data(item_value) -                if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style): -                    best_style = False -                if not (isinstance(node_value, yaml.ScalarNode) and not node_value.style): -                    best_style = False -                value.append((node_key, node_value)) -            if flow_style is None: -                if self.default_flow_style is not None: -                    node.flow_style = self.default_flow_style -                else: -                    node.flow_style = best_style -            return node - -    SafeDumper.add_representer( -        decimal.Decimal, -        SafeDumper.represent_decimal -    ) -    SafeDumper.add_representer( -        OrderedDict, -        yaml.representer.SafeRepresenter.represent_dict -    ) -    # SafeDumper.add_representer( -    #     DictWithMetadata, -    #     yaml.representer.SafeRepresenter.represent_dict -    # ) -    # SafeDumper.add_representer( -    #     OrderedDictWithMetadata, -    #     yaml.representer.SafeRepresenter.represent_dict -    # ) -    SafeDumper.add_representer( -        types.GeneratorType, -        yaml.representer.SafeRepresenter.represent_list -    ) diff --git a/tests/test_renderers.py b/tests/test_renderers.py index eb163ea5..2c8da2dc 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -9,11 +9,9 @@ from django.test import TestCase  from django.utils import six  from django.utils.translation import ugettext_lazy as _  from rest_framework import status, permissions -from rest_framework.compat import yaml, BytesIO  from rest_framework.response import Response  from rest_framework.views import APIView -from rest_framework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer, BrowsableAPIRenderer -from rest_framework.parsers import YAMLParser +from rest_framework.renderers import BaseRenderer, JSONRenderer, BrowsableAPIRenderer  from rest_framework.settings import api_settings  from rest_framework.test import APIRequestFactory  from collections import MutableMapping @@ -394,55 +392,6 @@ class AsciiJSONRendererTests(TestCase):          self.assertEqual(content, '{"countries":["United Kingdom","France","Espa\\u00f1a"]}'.encode('utf-8')) -if yaml: -    _yaml_repr = 'foo: [bar, baz]\n' - -    class YAMLRendererTests(TestCase): -        """ -        Tests specific to the YAML Renderer -        """ - -        def test_render(self): -            """ -            Test basic YAML rendering. -            """ -            obj = {'foo': ['bar', 'baz']} -            renderer = YAMLRenderer() -            content = renderer.render(obj, 'application/yaml') -            self.assertEqual(content.decode('utf-8'), _yaml_repr) - -        def test_render_and_parse(self): -            """ -            Test rendering and then parsing returns the original object. -            IE obj -> render -> parse -> obj. -            """ -            obj = {'foo': ['bar', 'baz']} - -            renderer = YAMLRenderer() -            parser = YAMLParser() - -            content = renderer.render(obj, 'application/yaml') -            data = parser.parse(BytesIO(content)) -            self.assertEqual(obj, data) - -        def test_render_decimal(self): -            """ -            Test YAML decimal rendering. -            """ -            renderer = YAMLRenderer() -            content = renderer.render({'field': Decimal('111.2')}, 'application/yaml') -            self.assertYAMLContains(content.decode('utf-8'), "field: '111.2'") - -        def assertYAMLContains(self, content, string): -            self.assertTrue(string in content, '%r not in %r' % (string, content)) - -        def test_proper_encoding(self): -            obj = {'countries': ['United Kingdom', 'France', 'España']} -            renderer = YAMLRenderer() -            content = renderer.render(obj, 'application/yaml') -            self.assertEqual(content.strip(), 'countries: [United Kingdom, France, España]'.encode('utf-8')) - -  # Tests for caching issue, #346  class CacheRenderTest(TestCase):      """ diff --git a/tests/test_templatetags.py b/tests/test_templatetags.py index b04a937e..0cee91f1 100644 --- a/tests/test_templatetags.py +++ b/tests/test_templatetags.py @@ -54,7 +54,7 @@ class Issue1386Tests(TestCase):  class URLizerTests(TestCase):      """ -    Test if both JSON and YAML URLs are transformed into links well +    Test if JSON URLs are transformed into links well      """      def _urlize_dict_check(self, data):          """ @@ -73,14 +73,3 @@ class URLizerTests(TestCase):          data['"foo_set": [\n    "http://api/foos/1/"\n], '] = \              '"foo_set": [\n    "<a href="http://api/foos/1/">http://api/foos/1/</a>"\n], '          self._urlize_dict_check(data) - -    def test_yaml_with_url(self): -        """ -        Test if YAML URLs are transformed into links well -        """ -        data = {} -        data['''{users: 'http://api/users/'}'''] = \ -            '''{users: '<a href="http://api/users/">http://api/users/</a>'}''' -        data['''foo_set: ['http://api/foos/1/']'''] = \ -            '''foo_set: ['<a href="http://api/foos/1/">http://api/foos/1/</a>']''' -        self._urlize_dict_check(data) @@ -20,7 +20,6 @@ deps =         django-filter==0.7         defusedxml==0.3         markdown>=2.1.0 -       PyYAML>=3.10  [testenv:py27-flake8]  deps = | 
