aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/fields.py7
-rw-r--r--rest_framework/serializers.py4
-rw-r--r--rest_framework/tests/test_serializer.py22
3 files changed, 31 insertions, 2 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 5ee75235..16485b41 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -443,8 +443,9 @@ class CharField(WritableField):
type_label = 'string'
form_field_class = forms.CharField
- def __init__(self, max_length=None, min_length=None, *args, **kwargs):
+ def __init__(self, max_length=None, min_length=None, allow_none=False, *args, **kwargs):
self.max_length, self.min_length = max_length, min_length
+ self.allow_none = allow_none
super(CharField, self).__init__(*args, **kwargs)
if min_length is not None:
self.validators.append(validators.MinLengthValidator(min_length))
@@ -452,7 +453,9 @@ class CharField(WritableField):
self.validators.append(validators.MaxLengthValidator(max_length))
def from_native(self, value):
- if isinstance(value, six.string_types) or value is None:
+ if value is None and not self.allow_none:
+ return ''
+ if isinstance(value, six.string_types):
return value
return smart_text(value)
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index fa935306..cbf73fc3 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -804,6 +804,10 @@ class ModelSerializer(Serializer):
issubclass(model_field.__class__, models.PositiveSmallIntegerField):
kwargs['min_value'] = 0
+ if model_field.null and \
+ issubclass(model_field.__class__, (models.CharField, models.TextField)):
+ kwargs['allow_none'] = True
+
attribute_dict = {
models.CharField: ['max_length'],
models.CommaSeparatedIntegerField: ['max_length'],
diff --git a/rest_framework/tests/test_serializer.py b/rest_framework/tests/test_serializer.py
index 86f365de..6d9b85ee 100644
--- a/rest_framework/tests/test_serializer.py
+++ b/rest_framework/tests/test_serializer.py
@@ -1124,6 +1124,20 @@ class BlankFieldTests(TestCase):
serializer = self.model_serializer_class(data={})
self.assertEqual(serializer.is_valid(), True)
+ def test_create_model_null_field_save(self):
+ """
+ Regression test for #1330.
+
+ https://github.com/tomchristie/django-rest-framework/pull/1330
+ """
+ serializer = self.model_serializer_class(data={'title': None})
+ self.assertEqual(serializer.is_valid(), True)
+
+ try:
+ serializer.save()
+ except Exception:
+ self.fail('Exception raised on save() after validation passes')
+
#test for issue #460
class SerializerPickleTests(TestCase):
@@ -1490,6 +1504,7 @@ class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
image_field = models.ImageField(max_length=1024, blank=True)
slug_field = models.SlugField(max_length=1024, blank=True)
url_field = models.URLField(max_length=1024, blank=True)
+ nullable_char_field = models.CharField(max_length=1024, blank=True, null=True)
class AMOAFSerializer(serializers.ModelSerializer):
class Meta:
@@ -1522,6 +1537,10 @@ class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
'url_field': [
('max_length', 1024),
],
+ 'nullable_char_field': [
+ ('max_length', 1024),
+ ('allow_none', True),
+ ],
}
def field_test(self, field):
@@ -1558,6 +1577,9 @@ class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
def test_url_field(self):
self.field_test('url_field')
+ def test_nullable_char_field(self):
+ self.field_test('nullable_char_field')
+
class DefaultValuesOnAutogeneratedFieldsTests(TestCase):