From 2169c85dbb011beb411a5c37ebc8d700b0984ce8 Mon Sep 17 00:00:00 2001 From: spiq Date: Fri, 4 Mar 2011 17:23:18 +0200 Subject: [PATCH] FomrParser now implements a work around for empty values in a list --- djangorestframework/content.py | 5 ++++- djangorestframework/parsers.py | 25 ++++++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/djangorestframework/content.py b/djangorestframework/content.py index dd40f8f1a..fe1a56d93 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 c334f7292..38f3db4b4 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 ``{: }``, 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)