Moving of nested form tokenization into parsers, plus some minor function naming changes

This commit is contained in:
Dan Stephenson 2013-09-06 00:43:29 +01:00
parent 53e7b9fafc
commit 4e0b3ad1b7
3 changed files with 22 additions and 12 deletions

View File

@ -13,6 +13,8 @@ from django.http.multipartparser import MultiPartParserError, parse_header, Chun
from rest_framework.compat import yaml, etree
from rest_framework.exceptions import ParseError
from rest_framework.compat import six
from rest_framework.utils.datastructures import TokenExpandedDict
from rest_framework.settings import api_settings
import json
import datetime
import decimal
@ -40,6 +42,16 @@ class BaseParser(object):
"""
raise NotImplementedError(".parse() must be overridden.")
def _parse_tokenization(self, data):
"""
Configuration dependant processing of input data, where character tokens
(such as periods '.') can be used to reshape for data into nested form,
for use with NestedModelSerializer.
"""
if api_settings.NESTED_FIELDS:
data = TokenExpandedDict(data)
return data
class JSONParser(BaseParser):
"""
@ -108,6 +120,8 @@ class FormParser(BaseParser):
parser_context = parser_context or {}
encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
data = QueryDict(stream.read(), encoding=encoding)
data = self._parse_tokenization(data)
return data
@ -134,6 +148,8 @@ class MultiPartParser(BaseParser):
try:
parser = DjangoMultiPartParser(meta, stream, upload_handlers, encoding)
data, files = parser.parse()
data = self._parse_tokenization(data)
return DataAndFiles(data, files)
except MultiPartParserError as exc:
raise ParseError('Multipart form parse error - %s' % six.u(exc))

View File

@ -13,7 +13,6 @@ from django.conf import settings
from django.http import QueryDict
from django.http.multipartparser import parse_header
from django.utils.datastructures import MultiValueDict
from rest_framework.utils.datastructures import DotExpandedDict
from rest_framework import HTTP_HEADER_ENCODING
from rest_framework import exceptions
from rest_framework.compat import BytesIO
@ -151,12 +150,8 @@ class Request(object):
Similar to usual behaviour of `request.POST`, except that it handles
arbitrary parsers, and also works on methods other than POST (eg PUT).
"""
if not _hasattr(self, '_data'):
self._load_data_and_files()
if api_settings.NESTED_FIELDS:
self._data = DotExpandedDict(self._data)
#if not _hasattr(self, '_data'):
# self._load_data_and_files()
return self._data
@property
@ -282,8 +277,7 @@ class Request(object):
return
# At this point we're committed to parsing the request as form data.
self._data = self._request.POST
self._files = self._request.FILES
self._data, self._files = self._parse()
# Method overloading - change the method and remove the param from the content.
if (self._METHOD_PARAM and

View File

@ -4,13 +4,13 @@ Utility functions for reshaping datastructures
from rest_framework.settings import api_settings
from django.http import QueryDict
class DotExpandedDict(QueryDict):
class TokenExpandedDict(QueryDict):
"""
A special dictionary constructor that takes a dictionary in which the keys
may contain dots to specify inner dictionaries. It's confusing, but this
example should make sense.
>>> d = DotExpandedDict({'person.1.firstname': ['Simon'], \
>>> d = TokenExpandedDict({'person.1.firstname': ['Simon'], \
'person.1.lastname': ['Willison'], \
'person.2.firstname': ['Adrian'], \
'person.2.lastname': ['Holovaty']})
@ -22,7 +22,7 @@ class DotExpandedDict(QueryDict):
{'lastname': ['Willison'], 'firstname': ['Simon']}
# Gotcha: Results are unpredictable if the dots are "uneven":
>>> DotExpandedDict({'c.1': 2, 'c.2': 3, 'c': 1})
>>> TokenExpandedDict({'c.1': 2, 'c.2': 3, 'c': 1})
{'c': 1}
"""
def __init__(self, key_to_list_mapping):