mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-12 17:22:27 +03:00
FomrParser now implements a work around for empty values in a list
This commit is contained in:
parent
033c0ae797
commit
2169c85dbb
|
@ -49,6 +49,9 @@ class SocketFile(File):
|
||||||
class OverloadedContentMixin(ContentMixin):
|
class OverloadedContentMixin(ContentMixin):
|
||||||
"""HTTP request content behaviour that also allows arbitrary content to be tunneled in form data."""
|
"""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."""
|
"""The name to use for the content override field in the POST form."""
|
||||||
CONTENT_PARAM = '_content'
|
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.
|
"""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."""
|
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):
|
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)
|
content_type = request.META.get('CONTENT_TYPE', None)
|
||||||
|
|
||||||
if (request.method == 'POST' and self.CONTENT_PARAM and
|
if (request.method == 'POST' and self.CONTENT_PARAM and
|
||||||
|
|
|
@ -79,11 +79,11 @@ class XMLParser(BaseParser):
|
||||||
media_type = 'application/xml'
|
media_type = 'application/xml'
|
||||||
|
|
||||||
class DataFlatener(object):
|
class DataFlatener(object):
|
||||||
|
#TODO : document + test
|
||||||
|
|
||||||
def flatten_data(self, data):
|
def flatten_data(self, data):
|
||||||
"""Given a data dictionary ``{<attr_name>: <value_list>}``, returns a flattened dictionary according to :meth:`FormParser.is_a_list`.
|
"""Given a data dictionary ``{<attr_name>: <value_list>}``, returns a flattened dictionary according to :meth:`FormParser.is_a_list`.
|
||||||
"""
|
"""
|
||||||
#TODO : document + test
|
|
||||||
flatdata = dict()
|
flatdata = dict()
|
||||||
for attr_name, attr_value in data.items():
|
for attr_name, attr_value in data.items():
|
||||||
if self.is_a_list(attr_name):
|
if self.is_a_list(attr_name):
|
||||||
|
@ -100,27 +100,32 @@ class DataFlatener(object):
|
||||||
|
|
||||||
def is_a_list(self, attr_name):
|
def is_a_list(self, attr_name):
|
||||||
""" """
|
""" """
|
||||||
#TODO: document
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class FormParser(BaseParser, DataFlatener):
|
class FormParser(BaseParser, DataFlatener):
|
||||||
"""The default parser for form data.
|
"""The default parser for form data.
|
||||||
Return a dict containing a single value for each non-reserved parameter.
|
Return a dict containing a single value for each non-reserved parameter.
|
||||||
"""
|
"""
|
||||||
|
# TODO: document flatening
|
||||||
# TODO: writing tests for PUT files + normal data
|
# TODO: writing tests for PUT files + normal data
|
||||||
|
# TODO: document EMPTY workaround
|
||||||
media_type = 'application/x-www-form-urlencoded'
|
media_type = 'application/x-www-form-urlencoded'
|
||||||
|
|
||||||
|
EMPTY_VALUE = 'EMPTY'
|
||||||
|
|
||||||
def parse(self, input):
|
def parse(self, input):
|
||||||
request = self.resource.request
|
request = self.resource.request
|
||||||
|
|
||||||
if request.method == 'PUT':
|
if request.method == 'PUT':
|
||||||
data = parse_qs(input)
|
data = parse_qs(input)
|
||||||
|
elif request.method == 'POST':
|
||||||
if request.method == 'POST':
|
|
||||||
# Django has already done the form parsing for us.
|
# Django has already done the form parsing for us.
|
||||||
data = request.POST
|
data = request.POST
|
||||||
|
|
||||||
|
# Flatening data and removing EMPTY_VALUEs from the lists
|
||||||
data = self.flatten_data(data)
|
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
|
# Strip any parameters that we are treating as reserved
|
||||||
for key in data:
|
for key in data:
|
||||||
|
@ -128,6 +133,16 @@ class FormParser(BaseParser, DataFlatener):
|
||||||
data.pop(key)
|
data.pop(key)
|
||||||
return data
|
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
|
# TODO: Allow parsers to specify multiple media_types
|
||||||
class MultipartParser(BaseParser, DataFlatener):
|
class MultipartParser(BaseParser, DataFlatener):
|
||||||
media_type = 'multipart/form-data'
|
media_type = 'multipart/form-data'
|
||||||
|
@ -139,12 +154,12 @@ class MultipartParser(BaseParser, DataFlatener):
|
||||||
upload_handlers = request._get_upload_handlers()
|
upload_handlers = request._get_upload_handlers()
|
||||||
django_mpp = DjangoMPParser(request.META, StringIO(input), upload_handlers)
|
django_mpp = DjangoMPParser(request.META, StringIO(input), upload_handlers)
|
||||||
data, files = django_mpp.parse()
|
data, files = django_mpp.parse()
|
||||||
|
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
# Django has already done the form parsing for us.
|
# Django has already done the form parsing for us.
|
||||||
data = request.POST
|
data = request.POST
|
||||||
files = request.FILES
|
files = request.FILES
|
||||||
|
|
||||||
|
# Flatening data, files and combining them
|
||||||
data = self.flatten_data(data)
|
data = self.flatten_data(data)
|
||||||
files = self.flatten_data(files)
|
files = self.flatten_data(files)
|
||||||
data.update(files)
|
data.update(files)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user