diff options
| author | sebpiq | 2011-03-11 14:34:39 +0200 |
|---|---|---|
| committer | sebpiq | 2011-03-11 14:34:39 +0200 |
| commit | d6c13a9e5caee653f7a8f3150c00aa574aa15700 (patch) | |
| tree | 77cfb477b5662677964e74a3a4fe27d687e3006e /djangorestframework/tests | |
| parent | 94199a484783d91317c8decb273ab60447ffdfd7 (diff) | |
| download | django-rest-framework-d6c13a9e5caee653f7a8f3150c00aa574aa15700.tar.bz2 | |
documentation + tests + debugging for formparsers
Diffstat (limited to 'djangorestframework/tests')
| -rw-r--r-- | djangorestframework/tests/__init__.py | 4 | ||||
| -rw-r--r-- | djangorestframework/tests/parsers.py | 72 |
2 files changed, 74 insertions, 2 deletions
diff --git a/djangorestframework/tests/__init__.py b/djangorestframework/tests/__init__.py index 55e386b5..5d5b652a 100644 --- a/djangorestframework/tests/__init__.py +++ b/djangorestframework/tests/__init__.py @@ -10,5 +10,5 @@ __test__ = dict() for module in modules: exec("from djangorestframework.tests.%s import __doc__ as module_doc" % module) exec("from djangorestframework.tests.%s import *" % module) - __test__['%s' % module] = module_doc or "" - + __test__[module] = module_doc or "" + diff --git a/djangorestframework/tests/parsers.py b/djangorestframework/tests/parsers.py new file mode 100644 index 00000000..a2831b63 --- /dev/null +++ b/djangorestframework/tests/parsers.py @@ -0,0 +1,72 @@ +""" +.. + >>> from djangorestframework.parsers import FormParser + >>> from djangorestframework.resource import Resource + >>> from djangorestframework.compat import RequestFactory + >>> from urllib import urlencode + >>> req = RequestFactory().get('/') + >>> some_resource = Resource() + >>> trash = some_resource.dispatch(req)# Some variables are set only when calling dispatch + +Data flatening +---------------- + +Here is some example data, which would eventually be sent along with a post request : + + >>> inpt = urlencode([ + ... ('key1', 'bla1'), + ... ('key2', 'blo1'), ('key2', 'blo2'), + ... ]) + +Default behaviour for :class:`parsers.FormParser`, is to return a single value for each parameter : + + >>> FormParser(some_resource).parse(inpt) == {'key1': 'bla1', 'key2': 'blo1'} + True + +However, you can customize this behaviour by subclassing :class:`parsers.FormParser`, and overriding :meth:`parsers.FormParser.is_a_list` : + + >>> class MyFormParser(FormParser): + ... + ... def is_a_list(self, key, val_list): + ... return len(val_list) > 1 + +This new parser only flattens the lists of parameters that contain a single value. + + >>> MyFormParser(some_resource).parse(inpt) == {'key1': 'bla1', 'key2': ['blo1', 'blo2']} + True + +Submitting an empty list +-------------------------- + +When submitting an empty select multiple, like this one :: + + <select multiple="multiple" name="key2"></select> + +The browsers usually strip the parameter completely. A hack to avoid this, and therefore being able to submit an empty select multiple, is to submit a value that tells the server that the list is empty :: + + <select multiple="multiple" name="key2"><option value="_empty"></select> + +:class:`parsers.FormParser` provides the server-side implementation for this hack. Considering the following posted data : + + >>> inpt = urlencode([ + ... ('key1', 'blo1'), ('key1', '_empty'), + ... ('key2', '_empty'), + ... ]) + +:class:`parsers.FormParser` strips the values ``_empty`` from all the lists. + + >>> MyFormParser(some_resource).parse(inpt) == {'key1': 'blo1'} + True + +Oh ... but wait a second, the parameter ``key2`` isn't even supposed to be a list, so the parser just stripped it. + + >>> class MyFormParser(FormParser): + ... + ... def is_a_list(self, key, val_list): + ... return key == 'key2' + ... + >>> MyFormParser(some_resource).parse(inpt) == {'key1': 'blo1', 'key2': []} + True + +Better like that. Note also that you can configure something else than ``_empty`` for the empty value by setting :class:`parsers.FormParser.EMPTY_VALUE`. +""" |
