aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspiq2011-03-04 17:23:18 +0200
committerspiq2011-03-04 17:23:18 +0200
commit2169c85dbb011beb411a5c37ebc8d700b0984ce8 (patch)
treef755b295dec22e57d37d5777422b77bb42215b69
parent033c0ae797e0bbb39a0687592d5b5f8eceb4d4dd (diff)
downloaddjango-rest-framework-2169c85dbb011beb411a5c37ebc8d700b0984ce8.tar.bz2
FomrParser now implements a work around for empty values in a list
-rw-r--r--djangorestframework/content.py5
-rw-r--r--djangorestframework/parsers.py25
2 files changed, 24 insertions, 6 deletions
diff --git a/djangorestframework/content.py b/djangorestframework/content.py
index dd40f8f1..fe1a56d9 100644
--- a/djangorestframework/content.py
+++ b/djangorestframework/content.py
@@ -49,6 +49,9 @@ class SocketFile(File):
class OverloadedContentMixin(ContentMixin):
"""HTTP request content behaviour that also allows arbitrary content to be tunneled in form data."""
+ #TODO: test PUT
+ #TODO: rewrite cleaner
+
"""The name to use for the content override field in the POST form."""
CONTENT_PARAM = '_content'
@@ -59,7 +62,7 @@ class OverloadedContentMixin(ContentMixin):
"""If the request contains content return a tuple of (content_type, content) otherwise return None.
Note that content_type may be None if it is unset."""
if not request.META.get('CONTENT_LENGTH', None) and not request.META.get('TRANSFER_ENCODING', None):
- return None
+ return None # TODO : Breaks, because determine_content should return a tuple.
content_type = request.META.get('CONTENT_TYPE', None)
if (request.method == 'POST' and self.CONTENT_PARAM and
diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py
index c334f729..38f3db4b 100644
--- a/djangorestframework/parsers.py
+++ b/djangorestframework/parsers.py
@@ -79,11 +79,11 @@ class XMLParser(BaseParser):
media_type = 'application/xml'
class DataFlatener(object):
+#TODO : document + test
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):
@@ -100,27 +100,32 @@ class DataFlatener(object):
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: document flatening
# TODO: writing tests for PUT files + normal data
+ # TODO: document EMPTY workaround
media_type = 'application/x-www-form-urlencoded'
+ EMPTY_VALUE = 'EMPTY'
+
def parse(self, input):
request = self.resource.request
if request.method == 'PUT':
data = parse_qs(input)
-
- if request.method == 'POST':
+ elif request.method == 'POST':
# Django has already done the form parsing for us.
data = request.POST
+ # Flatening data and removing EMPTY_VALUEs from the lists
data = self.flatten_data(data)
+ for key in filter(lambda k: self.is_a_list(k), data):
+ self.remove_empty_val(data[key])
# Strip any parameters that we are treating as reserved
for key in data:
@@ -128,6 +133,16 @@ class FormParser(BaseParser, DataFlatener):
data.pop(key)
return data
+ def remove_empty_val(self, val_list):
+ """ """
+ while(1): # Because there might be several times EMPTY_VALUE in the list
+ try:
+ ind = val_list.index(self.EMPTY_VALUE)
+ except ValueError:
+ break
+ else:
+ val_list.pop(ind)
+
# TODO: Allow parsers to specify multiple media_types
class MultipartParser(BaseParser, DataFlatener):
media_type = 'multipart/form-data'
@@ -139,12 +154,12 @@ class MultipartParser(BaseParser, DataFlatener):
upload_handlers = request._get_upload_handlers()
django_mpp = DjangoMPParser(request.META, StringIO(input), upload_handlers)
data, files = django_mpp.parse()
-
elif request.method == 'POST':
# Django has already done the form parsing for us.
data = request.POST
files = request.FILES
+ # Flatening data, files and combining them
data = self.flatten_data(data)
files = self.flatten_data(files)
data.update(files)