From 0a167a54fdbf9ceba2a1513636a50bf4c89efa66 Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Tue, 17 Jan 2012 10:58:42 +0000 Subject: [PATCH] Added an additional attribute `unknown_form_fields` to `FormResource` If the attribute is set to `True`, the validation method will not raise an `ErrorResponse` with status 400 but silently strip out unexpected fields on the form and only return the validated data. --- djangorestframework/resources.py | 13 +++++++++++-- djangorestframework/tests/validators.py | 12 ++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py index 68b285b91..d2651036c 100644 --- a/djangorestframework/resources.py +++ b/djangorestframework/resources.py @@ -78,13 +78,22 @@ class FormResource(Resource): This can be overridden by a :attr:`form` attribute on the :class:`views.View`. """ + unknown_form_fields = False + """ + Flag to check for unknown fields when validating a form. If set to false and + we receive request data that is not expected by the form it raises an + :exc:`response.ErrorResponse` with status code 400. If set to true, only + expected fields are validated. + """ + def validate_request(self, data, files=None): """ Given some content as input return some cleaned, validated content. Raises a :exc:`response.ErrorResponse` with status code 400 (Bad Request) on failure. - Validation is standard form validation, with an additional constraint that *no extra unknown fields* may be supplied. + Validation is standard form validation, with an additional constraint that *no extra unknown fields* may be supplied + if :attr:`self.unknown_form_fields` is ``True``. On failure the :exc:`response.ErrorResponse` content is a dict which may contain :obj:`'errors'` and :obj:`'field-errors'` keys. If the :obj:`'errors'` key exists it is a list of strings of non-field errors. @@ -132,7 +141,7 @@ class FormResource(Resource): 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: + if bound_form.is_valid() and (self.unknown_form_fields or not unknown_fields): # Validation succeeded... cleaned_data = bound_form.cleaned_data diff --git a/djangorestframework/tests/validators.py b/djangorestframework/tests/validators.py index 18c8c3137..c316f209a 100644 --- a/djangorestframework/tests/validators.py +++ b/djangorestframework/tests/validators.py @@ -138,6 +138,14 @@ class TestFormValidation(TestCase): content = {'qwerty': 'uiop', 'extra': 'extra'} validator._validate(content, None, allowed_extra_fields=('extra',)) + def validation_allows_unknown_fields_if_explicitly_allowed(self, validator): + """If we set ``unknown_form_fields`` on the form resource, then don't + raise errors on unexpected request data""" + content = {'qwerty': 'uiop', 'extra': 'extra'} + validator.unknown_form_fields = True + self.assertDictEqual({'qwerty': u'uiop'}, validator.validate_request(content, None), "Resource didn't accept unknown fields.") + validator.unknown_form_fields = False + def validation_does_not_require_extra_fields_if_explicitly_set(self, validator): """If we include an allowed_extra_fields paramater on _validate, then do not fail if we do not have fields with those names.""" content = {'qwerty': 'uiop'} @@ -201,6 +209,10 @@ class TestFormValidation(TestCase): def test_validation_allows_extra_fields_if_explicitly_set(self): validator = self.MockFormResource(self.MockFormView()) self.validation_allows_extra_fields_if_explicitly_set(validator) + + def test_validation_allows_unknown_fields_if_explicitly_allowed(self): + validator = self.MockFormResource(self.MockFormView()) + self.validation_allows_unknown_fields_if_explicitly_allowed(validator) def test_validation_does_not_require_extra_fields_if_explicitly_set(self): validator = self.MockFormResource(self.MockFormView())