diff options
| author | Tom Christie | 2012-10-30 14:32:31 +0000 |
|---|---|---|
| committer | Tom Christie | 2012-10-30 14:32:31 +0000 |
| commit | 9b30dab4f772f67a626e176dc4fae0a3ef9c2c81 (patch) | |
| tree | ca138abf4792f58ffa28684f784f201ee1eef6d7 /djangorestframework/parsers.py | |
| parent | 7e5b1501b5cede61a9391fb1a751d2ebcdb37031 (diff) | |
| parent | 4e7805cb24d73e7f706318b5e5a27e3f9ba39d14 (diff) | |
| download | django-rest-framework-9b30dab4f772f67a626e176dc4fae0a3ef9c2c81.tar.bz2 | |
Merge branch 'restframework2' into rest-framework-2-merge2.0.0
Conflicts:
.gitignore
.travis.yml
AUTHORS
README.rst
djangorestframework/mixins.py
djangorestframework/renderers.py
djangorestframework/resources.py
djangorestframework/serializer.py
djangorestframework/templates/djangorestframework/base.html
djangorestframework/templates/djangorestframework/login.html
djangorestframework/templatetags/add_query_param.py
djangorestframework/tests/accept.py
djangorestframework/tests/authentication.py
djangorestframework/tests/content.py
djangorestframework/tests/reverse.py
djangorestframework/tests/serializer.py
djangorestframework/views.py
docs/examples.rst
docs/examples/blogpost.rst
docs/examples/modelviews.rst
docs/examples/objectstore.rst
docs/examples/permissions.rst
docs/examples/pygments.rst
docs/examples/views.rst
docs/howto/alternativeframeworks.rst
docs/howto/mixin.rst
docs/howto/reverse.rst
docs/howto/usingurllib2.rst
docs/index.rst
docs/topics/release-notes.md
examples/sandbox/views.py
rest_framework/__init__.py
rest_framework/compat.py
rest_framework/utils/breadcrumbs.py
setup.py
Diffstat (limited to 'djangorestframework/parsers.py')
| -rw-r--r-- | djangorestframework/parsers.py | 258 |
1 files changed, 0 insertions, 258 deletions
diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py deleted file mode 100644 index a19582b7..00000000 --- a/djangorestframework/parsers.py +++ /dev/null @@ -1,258 +0,0 @@ -""" -Django supports parsing the content of an HTTP request, but only for form POST requests. -That behavior is sufficient for dealing with standard HTML forms, but it doesn't map well -to general HTTP requests. - -We need a method to be able to: - -1.) Determine the parsed content on a request for methods other than POST (eg typically also PUT) - -2.) Determine the parsed content on a request for media types other than application/x-www-form-urlencoded - and multipart/form-data. (eg also handle multipart/json) -""" - -from django.http import QueryDict -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 -from xml.etree import ElementTree as ET -from djangorestframework.compat import ETParseError -from xml.parsers.expat import ExpatError -import datetime -import decimal - - -__all__ = ( - 'BaseParser', - 'JSONParser', - 'PlainTextParser', - 'FormParser', - 'MultiPartParser', - 'YAMLParser', - 'XMLParser' -) - - -class BaseParser(object): - """ - All parsers should extend :class:`BaseParser`, specifying a :attr:`media_type` attribute, - and overriding the :meth:`parse` method. - """ - - media_type = None - - def __init__(self, view): - """ - Initialize the parser with the ``View`` instance as state, - in case the parser needs to access any metadata on the :obj:`View` object. - """ - self.view = view - - def can_handle_request(self, content_type): - """ - Returns :const:`True` if this parser is able to deal with the given *content_type*. - - The default implementation for this function is to check the *content_type* - argument against the :attr:`media_type` attribute set on the class to see if - they match. - - This may be overridden to provide for other behavior, but typically you'll - instead want to just set the :attr:`media_type` attribute on the class. - """ - return media_type_matches(self.media_type, content_type) - - def parse(self, stream): - """ - Given a *stream* to read from, return the deserialized output. - Should return a 2-tuple of (data, files). - """ - raise NotImplementedError("BaseParser.parse() Must be overridden to be implemented.") - - -class JSONParser(BaseParser): - """ - Parses JSON-serialized data. - """ - - media_type = 'application/json' - - 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 (json.load(stream), None) - except ValueError, exc: - raise ErrorResponse(status.HTTP_400_BAD_REQUEST, - {'detail': 'JSON parse error - %s' % unicode(exc)}) - - -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, yaml.parser.ParserError), exc: - content = {'detail': 'YAML parse error - %s' % unicode(exc)} - raise ErrorResponse(status.HTTP_400_BAD_REQUEST, content) - - -class PlainTextParser(BaseParser): - """ - Plain text parser. - """ - - media_type = 'text/plain' - - def parse(self, stream): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will simply be a string representing the body of the request. - `files` will always be `None`. - """ - return (stream.read(), None) - - -class FormParser(BaseParser): - """ - Parser for form data. - """ - - media_type = 'application/x-www-form-urlencoded' - - def parse(self, stream): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will be a :class:`QueryDict` containing all the form parameters. - `files` will always be :const:`None`. - """ - data = QueryDict(stream.read()) - return (data, None) - - -class MultiPartParser(BaseParser): - """ - Parser for multipart form data, which may include file data. - """ - - media_type = 'multipart/form-data' - - def parse(self, stream): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will be a :class:`QueryDict` containing all the form parameters. - `files` will be a :class:`QueryDict` containing all the form files. - """ - upload_handlers = self.view.request._get_upload_handlers() - try: - django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers) - return django_parser.parse() - except MultiPartParserError, exc: - raise ErrorResponse(status.HTTP_400_BAD_REQUEST, - {'detail': 'multipart parse error - %s' % unicode(exc)}) - - -class XMLParser(BaseParser): - """ - XML parser. - """ - - media_type = 'application/xml' - - def parse(self, stream): - """ - Returns a 2-tuple of `(data, files)`. - - `data` will simply be a string representing the body of the request. - `files` will always be `None`. - """ - try: - tree = ET.parse(stream) - except (ExpatError, ETParseError, ValueError), exc: - content = {'detail': 'XML parse error - %s' % unicode(exc)} - raise ErrorResponse(status.HTTP_400_BAD_REQUEST, content) - data = self._xml_convert(tree.getroot()) - - return (data, None) - - def _xml_convert(self, element): - """ - convert the xml `element` into the corresponding python object - """ - - children = element.getchildren() - - if len(children) == 0: - return self._type_convert(element.text) - else: - # if the fist child tag is list-item means all children are list-item - if children[0].tag == "list-item": - data = [] - for child in children: - data.append(self._xml_convert(child)) - else: - data = {} - for child in children: - data[child.tag] = self._xml_convert(child) - - return data - - def _type_convert(self, value): - """ - Converts the value returned by the XMl parse into the equivalent - Python type - """ - if value is None: - return value - - try: - return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S') - except ValueError: - pass - - try: - return int(value) - except ValueError: - pass - - try: - return decimal.Decimal(value) - except decimal.InvalidOperation: - pass - - return value - - -DEFAULT_PARSERS = ( - JSONParser, - FormParser, - MultiPartParser, - XMLParser -) - -if yaml: - DEFAULT_PARSERS += (YAMLParser, ) -else: - YAMLParser = None - |
