From 03f801c7ffb7e74fc12690ede9468769f92f2f68 Mon Sep 17 00:00:00 2001 From: Ian Strachan Date: Sat, 27 Oct 2012 15:37:02 +0100 Subject: [PATCH 1/2] Failing unit test for issue #324 --- rest_framework/tests/models.py | 4 ++++ rest_framework/tests/serializer.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 0ee18c697..453dfc2cb 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -111,3 +111,7 @@ class BlogPost(RESTFrameworkModel): class BlogPostComment(RESTFrameworkModel): text = models.TextField() blog_post = models.ForeignKey(BlogPost) + +# Model for issue #324 +class BlankFieldModel(RESTFrameworkModel): + title = models.CharField(max_length=100, blank=True) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 67c97f0ff..afb7f3dbc 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -436,3 +436,19 @@ class ManyRelatedTests(TestCase): } self.assertEqual(serializer.data, expected) + + +# Test for issue #324 +class BlankFieldTests(TestCase): + def setUp(self): + + class BlankFieldModelSerializer(serializers.ModelSerializer): + class Meta: + model = BlankFieldModel + + self.serializer_class = BlankFieldModelSerializer + + def test_create_blank_field(self): + data = {'title': ''} + serializer = self.serializer_class(data) + self.assertEquals(serializer.is_valid(), True) From 28ba8586abde1bdbbe120a0e6c64a7a4ea164284 Mon Sep 17 00:00:00 2001 From: Ian Strachan Date: Mon, 29 Oct 2012 21:23:24 +0000 Subject: [PATCH 2/2] #324 Fix for blank=True not being respected on CharField --- rest_framework/fields.py | 11 +++++++++ rest_framework/serializers.py | 3 +++ rest_framework/tests/serializer.py | 39 +++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 85e6ee318..c434f6755 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -442,12 +442,23 @@ class CharField(WritableField): def __init__(self, max_length=None, min_length=None, *args, **kwargs): self.max_length, self.min_length = max_length, min_length + self.blank = kwargs.pop('blank', False) super(CharField, self).__init__(*args, **kwargs) if min_length is not None: self.validators.append(validators.MinLengthValidator(min_length)) if max_length is not None: self.validators.append(validators.MaxLengthValidator(max_length)) + def validate(self, value): + """ + Validates that the value is supplied (if required). + """ + # if empty string and allow blank + if self.blank and not value: + return + else: + super(CharField, self).validate(value) + def from_native(self, value): if isinstance(value, basestring) or value is None: return value diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 8a8953431..5b012ff56 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -420,6 +420,9 @@ class ModelSerializer(Serializer): kwargs['choices'] = model_field.flatchoices return ChoiceField(**kwargs) + if model_field.__class__ == models.TextField or model_field.__class__ == models.CharField: + kwargs['blank'] = model_field.blank + field_mapping = { models.FloatField: FloatField, models.IntegerField: IntegerField, diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index afb7f3dbc..d0e4b5e58 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -446,9 +446,42 @@ class BlankFieldTests(TestCase): class Meta: model = BlankFieldModel - self.serializer_class = BlankFieldModelSerializer + class BlankFieldSerializer(serializers.Serializer): + title = serializers.CharField(blank=True) + + class NotBlankFieldModelSerializer(serializers.ModelSerializer): + class Meta: + model = BasicModel + + class NotBlankFieldSerializer(serializers.Serializer): + title = serializers.CharField() + + self.model_serializer_class = BlankFieldModelSerializer + self.serializer_class = BlankFieldSerializer + self.not_blank_model_serializer_class = NotBlankFieldModelSerializer + self.not_blank_serializer_class = NotBlankFieldSerializer + self.data = {'title': ''} def test_create_blank_field(self): - data = {'title': ''} - serializer = self.serializer_class(data) + serializer = self.serializer_class(self.data) self.assertEquals(serializer.is_valid(), True) + + def test_create_model_blank_field(self): + serializer = self.model_serializer_class(self.data) + self.assertEquals(serializer.is_valid(), True) + + def test_create_not_blank_field(self): + """ + Test to ensure blank data in a field not marked as blank=True + is considered invalid in a non-model serializer + """ + serializer = self.not_blank_serializer_class(self.data) + self.assertEquals(serializer.is_valid(), False) + + def test_create_model_not_blank_field(self): + """ + Test to ensure blank data in a field not marked as blank=True + is considered invalid in a model serializer + """ + serializer = self.not_blank_model_serializer_class(self.data) + self.assertEquals(serializer.is_valid(), False)