aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--djangorestframework/content.py7
-rw-r--r--djangorestframework/parsers.py28
2 files changed, 24 insertions, 11 deletions
diff --git a/djangorestframework/content.py b/djangorestframework/content.py
index 96050029..48f327b6 100644
--- a/djangorestframework/content.py
+++ b/djangorestframework/content.py
@@ -28,10 +28,12 @@ class StandardContentMixin(ContentMixin):
class OverloadedContentMixin(ContentMixin):
"""HTTP request content behaviour that also allows arbitrary content to be tunneled in form data."""
- """The name to use for the content override field in the POST form. Set this to *None* to desactivate content overloading."""
+ """The name to use for the content override field in the POST form.
+ Set this to *None* to desactivate content overloading."""
CONTENT_PARAM = '_content'
- """The name to use for the content-type override field in the POST form. Taken into account only if content overloading is activated."""
+ """The name to use for the content-type override field in the POST form.
+ Taken into account only if content overloading is activated."""
CONTENTTYPE_PARAM = '_contenttype'
def determine_content(self, request):
@@ -48,6 +50,7 @@ class OverloadedContentMixin(ContentMixin):
content_type = None
if self.CONTENTTYPE_PARAM and request.POST.get(self.CONTENTTYPE_PARAM, None):
content_type = request.POST.get(self.CONTENTTYPE_PARAM, None)
+ request.META['CONTENT_TYPE'] = content_type
return (content_type, request.POST[self.CONTENT_PARAM])
else:
diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py
index 4659f24b..081fa689 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
+ """Utility object for flatening dictionaries of lists. Useful for "urlencoded" decoded data."""
def flatten_data(self, data):
- """Given a data dictionary ``{<key>: <value_list>}``, returns a flattened dictionary according to :meth:`FormParser.is_a_list`.
- """
+ """Given a data dictionary {<key>: <value_list>}, returns a flattened dictionary
+ with information provided by the method "is_a_list"."""
flatdata = dict()
for key, attr_value in data.items():
if self.is_a_list(key):
@@ -98,20 +98,27 @@ class DataFlatener(object):
flatdata[key] = attr_value
return flatdata
- def is_a_list(self, key):
- """ """
+ def is_a_list(self, key, val):
+ """Returns True if the parameter with name *key* is expected to be a list, or False otherwise.
+ *val* which is the received value for parameter *key* can be used to guess the answer."""
return False
class FormParser(BaseParser, DataFlatener):
"""The default parser for form data.
Return a dict containing a single value for each non-reserved parameter.
+
+ In order to handle select multiple (and having possibly more than a single value for each parameter),
+ you can customize the output by subclassing the method 'is_a_list'.
+
"""
- # 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'
+ """The value of the parameter when the select multiple is empty.
+ Browsers are usually stripping the select multiple that have no option selected from the parameters sent.
+ A common hack to avoid this is to send the parameter with a value specifying that the list is empty.
+ This value will always be stripped before the data is returned."""
+ EMPTY_VALUE = '_empty'
def parse(self, input):
data = parse_qs(input)
@@ -142,8 +149,11 @@ class MultipartParser(BaseParser, DataFlatener):
media_type = 'multipart/form-data'
def parse(self, input):
- request = self.resource.request
+ request = self.resource.request
+ #TODO : that's pretty dumb : files are loaded with
+ #upload_handlers, but as we read the request body completely (input),
+ #then it kind of misses the point. Why not input as a stream ?
upload_handlers = request._get_upload_handlers()
django_mpp = DjangoMPParser(request.META, StringIO(input), upload_handlers)
data, files = django_mpp.parse()