aboutsummaryrefslogtreecommitdiffstats
path: root/djangorestframework/parsers.py
diff options
context:
space:
mode:
authorspiq2011-03-04 17:06:44 +0200
committerspiq2011-03-04 17:06:44 +0200
commit033c0ae797e0bbb39a0687592d5b5f8eceb4d4dd (patch)
tree35d2dcf3ce18d0563bc5672aa4755093787c19c2 /djangorestframework/parsers.py
parent91b33659b562f26665cebc3c7d8aba6d57e9386c (diff)
downloaddjango-rest-framework-033c0ae797e0bbb39a0687592d5b5f8eceb4d4dd.tar.bz2
forms and multipat parsers now flaten data
Diffstat (limited to 'djangorestframework/parsers.py')
-rw-r--r--djangorestframework/parsers.py57
1 files changed, 37 insertions, 20 deletions
diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py
index e5dd7df4..c334f729 100644
--- a/djangorestframework/parsers.py
+++ b/djangorestframework/parsers.py
@@ -78,12 +78,36 @@ class JSONParser(BaseParser):
class XMLParser(BaseParser):
media_type = 'application/xml'
-
-class FormParser(BaseParser):
+class DataFlatener(object):
+
+ def flatten_data(self, data):
+ """Given a data dictionary ``{<attr_name>: <value_list>}``, returns a flattened dictionary according to :meth:`FormParser.is_a_list`.
+ """
+ #TODO : document + test
+ flatdata = dict()
+ for attr_name, attr_value in data.items():
+ if self.is_a_list(attr_name):
+ if isinstance(attr_value, list):
+ flatdata[attr_name] = attr_value
+ else:
+ flatdata[attr_name] = [attr_value]
+ else:
+ if isinstance(attr_value, list):
+ flatdata[attr_name] = attr_value[0]
+ else:
+ flatdata[attr_name] = attr_value
+ return flatdata
+
+ def is_a_list(self, attr_name):
+ """ """
+ #TODO: document
+ return False
+
+class FormParser(BaseParser, DataFlatener):
"""The default parser for form data.
Return a dict containing a single value for each non-reserved parameter.
"""
- # TODO: not good, because posted/put lists are flattened !!!
+ # TODO: writing tests for PUT files + normal data
media_type = 'application/x-www-form-urlencoded'
def parse(self, input):
@@ -91,13 +115,12 @@ class FormParser(BaseParser):
if request.method == 'PUT':
data = parse_qs(input)
- # Flattening the parsed query data
- for key, val in data.items():
- data[key] = val[0]
if request.method == 'POST':
# Django has already done the form parsing for us.
- data = dict(request.POST.items())
+ data = request.POST
+
+ data = self.flatten_data(data)
# Strip any parameters that we are treating as reserved
for key in data:
@@ -106,7 +129,7 @@ class FormParser(BaseParser):
return data
# TODO: Allow parsers to specify multiple media_types
-class MultipartParser(FormParser):
+class MultipartParser(BaseParser, DataFlatener):
media_type = 'multipart/form-data'
def parse(self, input):
@@ -116,19 +139,14 @@ class MultipartParser(FormParser):
upload_handlers = request._get_upload_handlers()
django_mpp = DjangoMPParser(request.META, StringIO(input), upload_handlers)
data, files = django_mpp.parse()
- data = dict(data)
- files = dict(files)
- if request.method == 'POST':
+ elif request.method == 'POST':
# Django has already done the form parsing for us.
- data = dict(request.POST)
- files = dict(request.FILES)
-
- # Flattening, then merging the POSTED/PUT data/files
- for key, val in dict(data).items():
- data[key] = val[0]
- for key, val in dict(files).items():
- files[key] = val[0].read()
+ data = request.POST
+ files = request.FILES
+
+ data = self.flatten_data(data)
+ files = self.flatten_data(files)
data.update(files)
# Strip any parameters that we are treating as reserved
@@ -136,4 +154,3 @@ class MultipartParser(FormParser):
if key in self.resource.RESERVED_FORM_PARAMS:
data.pop(key)
return data
-