From a848923a394853e7ed30f14189703c4afaf0c772 Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Thu, 9 Jun 2011 16:24:27 +0100 Subject: [PATCH 1/3] Returning the dict from `parse_qs` in `FormParser` fails on forms. Use `QueryDict` instead to return a value that is compatible with forms. --- djangorestframework/parsers.py | 3 ++- djangorestframework/tests/parsers.py | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 726e09e97..4f49c20a9 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -11,6 +11,7 @@ We need a method to be able to: and multipart/form-data. (eg also handle multipart/json) """ +from django.http import QueryDict from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser from django.utils import simplejson as json from djangorestframework import status @@ -117,7 +118,7 @@ class FormParser(BaseParser): `data` will be a :class:`QueryDict` containing all the form parameters. `files` will always be :const:`None`. """ - data = parse_qs(stream.read(), keep_blank_values=True) + data = QueryDict(stream.read()) return (data, None) diff --git a/djangorestframework/tests/parsers.py b/djangorestframework/tests/parsers.py index 3ab1a61c8..656d63c82 100644 --- a/djangorestframework/tests/parsers.py +++ b/djangorestframework/tests/parsers.py @@ -131,3 +131,30 @@ # self.assertEqual(data['key1'], 'val1') # self.assertEqual(files['file1'].read(), 'blablabla') +from StringIO import StringIO +from cgi import parse_qs +from django import forms +from django.test import TestCase +from djangorestframework.parsers import FormParser + +class Form(forms.Form): + field1 = forms.CharField(max_length=3) + field2 = forms.CharField() + +class TestFormParser(TestCase): + def setUp(self): + self.string = "field1=abc&field2=defghijk" + + def test_fail(self): + """ Demonstrate that `parse_qs` fails on forms """ + data = parse_qs(self.string, keep_blank_values=True) + self.assertEqual(Form(data).is_valid(), False) + + def test_parse(self): + """ Make sure the `QueryDict` works OK """ + parser = FormParser(None) + + stream = StringIO(self.string) + (data, files) = parser.parse(stream) + + self.assertEqual(Form(data).is_valid(), True) From d034c0fe4f1dbae77dccc9709335ad877700ed54 Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Thu, 9 Jun 2011 16:27:45 +0100 Subject: [PATCH 2/3] Removed unused imports --- djangorestframework/parsers.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index 4f49c20a9..3346a26e2 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -15,9 +15,7 @@ from django.http import QueryDict from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser from django.utils import simplejson as json from djangorestframework import status -from djangorestframework.compat import parse_qs from djangorestframework.response import ErrorResponse -from djangorestframework.utils import as_tuple from djangorestframework.utils.mediatypes import media_type_matches __all__ = ( From 06177b8d4b77bcfe7d945d2a593ab3458c8fa528 Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Fri, 10 Jun 2011 12:36:04 +0100 Subject: [PATCH 3/3] `bound_form.cleaned_data` already returns the file data if there was any. `bound_form.files` returns a `MultiValueDict` which errors when passing `.CONTENT` into a model constructor. --- djangorestframework/resources.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py index 4b81bf793..cc4b64712 100644 --- a/djangorestframework/resources.py +++ b/djangorestframework/resources.py @@ -241,14 +241,12 @@ class FormResource(Resource): # In addition to regular validation we also ensure no additional fields are being passed in... unknown_fields = seen_fields_set - (form_fields_set | allowed_extra_fields_set) unknown_fields = unknown_fields - set(('csrfmiddlewaretoken', '_accept', '_method')) # TODO: Ugh. - + # Check using both regular validation, and our stricter no additional fields rule if bound_form.is_valid() and not unknown_fields: # Validation succeeded... cleaned_data = bound_form.cleaned_data - cleaned_data.update(bound_form.files) - # Add in any extra fields to the cleaned content... for key in (allowed_extra_fields_set & seen_fields_set) - set(cleaned_data.keys()): cleaned_data[key] = data[key]