diff options
| author | Tom Christie | 2011-07-01 17:44:08 +0100 |
|---|---|---|
| committer | Tom Christie | 2011-07-01 17:44:08 +0100 |
| commit | f7b7778a79bad4124a6f50bf461f206a6d71fa90 (patch) | |
| tree | 2bd1b84a90dec5724cda3d89b3a9faf5ca298961 /djangorestframework | |
| parent | c3babe751a6bab7c7888f173b7853a65ba2ea35e (diff) | |
| parent | f67c0651baf1cea65221b4fb7f4df11a54abed90 (diff) | |
| download | django-rest-framework-f7b7778a79bad4124a6f50bf461f206a6d71fa90.tar.bz2 | |
pull in markos changes, minor tweaks to yaml stuff
Diffstat (limited to 'djangorestframework')
| -rw-r--r-- | djangorestframework/compat.py | 7 | ||||
| -rw-r--r-- | djangorestframework/parsers.py | 24 | ||||
| -rw-r--r-- | djangorestframework/renderers.py | 33 | ||||
| -rw-r--r-- | djangorestframework/templates/renderer.html | 8 | ||||
| -rw-r--r-- | djangorestframework/tests/renderers.py | 39 | ||||
| -rw-r--r-- | djangorestframework/views.py | 3 |
6 files changed, 102 insertions, 12 deletions
diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py index 827b4adf..230172c3 100644 --- a/djangorestframework/compat.py +++ b/djangorestframework/compat.py @@ -156,6 +156,7 @@ except ImportError: def head(self, request, *args, **kwargs): return self.get(request, *args, **kwargs) +# Markdown is optional try: import markdown import re @@ -204,3 +205,9 @@ try: except ImportError: apply_markdown = None + +# Yaml is optional +try: + import yaml +except ImportError: + yaml = None diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 37882984..5f19c521 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -16,15 +16,18 @@ from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser from django.http.multipartparser import MultiPartParserError from django.utils import simplejson as json from djangorestframework import status +from djangorestframework.compat import yaml from djangorestframework.response import ErrorResponse from djangorestframework.utils.mediatypes import media_type_matches + __all__ = ( 'BaseParser', 'JSONParser', 'PlainTextParser', 'FormParser', 'MultiPartParser', + 'YAMLParser', ) @@ -85,6 +88,27 @@ class JSONParser(BaseParser): {'detail': 'JSON parse error - %s' % unicode(exc)}) +if yaml: + class YAMLParser(BaseParser): + """ + Parses YAML-serialized data. + """ + + media_type = 'application/yaml' + + def parse(self, stream): + """ + Returns a 2-tuple of `(data, files)`. + + `data` will be an object which is the parsed content of the response. + `files` will always be `None`. + """ + try: + return (yaml.safe_load(stream), None) + except ValueError, exc: + raise ErrorResponse(status.HTTP_400_BAD_REQUEST, + {'detail': 'YAML parse error - %s' % unicode(exc)}) + class PlainTextParser(BaseParser): """ diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index e09e2abc..aae2cab2 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -11,16 +11,14 @@ from django.core.serializers.json import DateTimeAwareJSONEncoder from django.template import RequestContext, loader from django.utils import simplejson as json -from djangorestframework import status -from djangorestframework.compat import apply_markdown + +from djangorestframework.compat import apply_markdown, yaml from djangorestframework.utils import dict2xml, url_resolves from djangorestframework.utils.breadcrumbs import get_breadcrumbs from djangorestframework.utils.description import get_name, get_description from djangorestframework.utils.mediatypes import get_media_type_params, add_media_type_param, media_type_matches from djangorestframework import VERSION -from decimal import Decimal -import re import string from urllib import quote_plus @@ -31,7 +29,8 @@ __all__ = ( 'DocumentingHTMLRenderer', 'DocumentingXHTMLRenderer', 'DocumentingPlainTextRenderer', - 'XMLRenderer' + 'XMLRenderer', + 'YAMLRenderer' ) @@ -131,6 +130,27 @@ class XMLRenderer(BaseRenderer): return dict2xml(obj) +if yaml: + class YAMLRenderer(BaseRenderer): + """ + Renderer which serializes to YAML. + """ + + media_type = 'application/yaml' + format = 'yaml' + + def render(self, obj=None, media_type=None): + """ + Renders *obj* into serialized YAML. + """ + if obj is None: + return '' + + return yaml.dump(obj) +else: + YAMLRenderer = None + + class TemplateRenderer(BaseRenderer): """ A Base class provided for convenience. @@ -361,4 +381,5 @@ DEFAULT_RENDERERS = ( JSONRenderer, DocumentingPlainTextRenderer, XMLRenderer ) - +if YAMLRenderer: + DEFAULT_RENDERERS += (YAMLRenderer,) diff --git a/djangorestframework/templates/renderer.html b/djangorestframework/templates/renderer.html index 5b32d1ec..3dd5faf3 100644 --- a/djangorestframework/templates/renderer.html +++ b/djangorestframework/templates/renderer.html @@ -8,6 +8,8 @@ #site-name a {color: #F4F379 !important;} .errorlist {display: inline !important} .errorlist li {display: inline !important; background: white !important; color: black !important; border: 0 !important;} + /* Custom styles */ + .version{font-size:8px;} </style> <link rel="stylesheet" type="text/css" href='{{ADMIN_MEDIA_PREFIX}}css/base.css'/> <link rel="stylesheet" type="text/css" href='{{ADMIN_MEDIA_PREFIX}}css/forms.css'/> @@ -18,7 +20,7 @@ <div id="header"> <div id="branding"> - <h1 id="site-name"><a href='http://django-rest-framework.org'>Django REST framework</a> <small>{{ version }}</small></h1> + <h1 id="site-name"><a href='http://django-rest-framework.org'>Django REST framework</a> <span class="version"> v {{ version }}</span></h1> </div> <div id="user-tools"> {% if user.is_active %}Welcome, {{ user }}.{% if logout_url %} <a href='{{ logout_url }}'>Log out</a>{% endif %}{% else %}Anonymous {% if login_url %}<a href='{{ login_url }}'>Log in</a>{% endif %}{% endif %} @@ -58,8 +60,8 @@ </form> {% endif %} - {# Only display the POST/PUT/DELETE forms if method tunneling via POST forms is enabled. #} - {% if METHOD_PARAM %} + {# Only display the POST/PUT/DELETE forms if method tunneling via POST forms is enabled and the user has permissions on this view. #} + {% if METHOD_PARAM and response.status != 403 %} {% if 'POST' in view.allowed_methods %} <form action="{{ request.get_full_path }}" method="post" {% if post_form.is_multipart %}enctype="multipart/form-data"{% endif %}> diff --git a/djangorestframework/tests/renderers.py b/djangorestframework/tests/renderers.py index bf135e55..d2046212 100644 --- a/djangorestframework/tests/renderers.py +++ b/djangorestframework/tests/renderers.py @@ -4,8 +4,8 @@ from django.test import TestCase from djangorestframework import status from djangorestframework.compat import View as DjangoView -from djangorestframework.renderers import BaseRenderer, JSONRenderer -from djangorestframework.parsers import JSONParser +from djangorestframework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer +from djangorestframework.parsers import JSONParser, YAMLParser from djangorestframework.mixins import ResponseMixin from djangorestframework.response import Response from djangorestframework.utils.mediatypes import add_media_type_param @@ -189,3 +189,38 @@ class JSONRendererTests(TestCase): content = renderer.render(obj, 'application/json') (data, files) = parser.parse(StringIO(content)) self.assertEquals(obj, data) + + + +if YAMLRenderer: + _yaml_repr = 'foo: [bar, baz]\n' + + + class YAMLRendererTests(TestCase): + """ + Tests specific to the JSON Renderer + """ + + def test_render(self): + """ + Test basic YAML rendering. + """ + obj = {'foo':['bar','baz']} + renderer = YAMLRenderer(None) + content = renderer.render(obj, 'application/yaml') + self.assertEquals(content, _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(None) + parser = YAMLParser(None) + + content = renderer.render(obj, 'application/yaml') + (data, files) = parser.parse(StringIO(content)) + self.assertEquals(obj, data)
\ No newline at end of file diff --git a/djangorestframework/views.py b/djangorestframework/views.py index 18d064e1..757d89db 100644 --- a/djangorestframework/views.py +++ b/djangorestframework/views.py @@ -44,7 +44,8 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): renderers.DocumentingHTMLRenderer, renderers.DocumentingXHTMLRenderer, renderers.DocumentingPlainTextRenderer, - renderers.XMLRenderer ) + renderers.XMLRenderer, + renderers.YAMLRenderer ) """ List of parsers the resource can parse the request with. |
