mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-27 12:04:02 +03:00
Merge pull request #1348 from yprez/none-to-empty-string_2.4
Coerce None to empty string
This commit is contained in:
commit
07cff7b37f
|
@ -157,23 +157,24 @@ Corresponds to `django.db.models.fields.BooleanField`.
|
||||||
## CharField
|
## CharField
|
||||||
|
|
||||||
A text representation, optionally validates the text to be shorter than `max_length` and longer than `min_length`.
|
A text representation, optionally validates the text to be shorter than `max_length` and longer than `min_length`.
|
||||||
|
If `allow_none` is `False` (default), `None` values will be converted to an empty string.
|
||||||
|
|
||||||
Corresponds to `django.db.models.fields.CharField`
|
Corresponds to `django.db.models.fields.CharField`
|
||||||
or `django.db.models.fields.TextField`.
|
or `django.db.models.fields.TextField`.
|
||||||
|
|
||||||
**Signature:** `CharField(max_length=None, min_length=None)`
|
**Signature:** `CharField(max_length=None, min_length=None, allow_none=False)`
|
||||||
|
|
||||||
## URLField
|
## URLField
|
||||||
|
|
||||||
Corresponds to `django.db.models.fields.URLField`. Uses Django's `django.core.validators.URLValidator` for validation.
|
Corresponds to `django.db.models.fields.URLField`. Uses Django's `django.core.validators.URLValidator` for validation.
|
||||||
|
|
||||||
**Signature:** `CharField(max_length=200, min_length=None)`
|
**Signature:** `CharField(max_length=200, min_length=None, allow_none=False)`
|
||||||
|
|
||||||
## SlugField
|
## SlugField
|
||||||
|
|
||||||
Corresponds to `django.db.models.fields.SlugField`.
|
Corresponds to `django.db.models.fields.SlugField`.
|
||||||
|
|
||||||
**Signature:** `CharField(max_length=50, min_length=None)`
|
**Signature:** `CharField(max_length=50, min_length=None, allow_none=False)`
|
||||||
|
|
||||||
## ChoiceField
|
## ChoiceField
|
||||||
|
|
||||||
|
|
|
@ -443,8 +443,9 @@ class CharField(WritableField):
|
||||||
type_label = 'string'
|
type_label = 'string'
|
||||||
form_field_class = forms.CharField
|
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.max_length, self.min_length = max_length, min_length
|
||||||
|
self.allow_none = allow_none
|
||||||
super(CharField, self).__init__(*args, **kwargs)
|
super(CharField, self).__init__(*args, **kwargs)
|
||||||
if min_length is not None:
|
if min_length is not None:
|
||||||
self.validators.append(validators.MinLengthValidator(min_length))
|
self.validators.append(validators.MinLengthValidator(min_length))
|
||||||
|
@ -452,7 +453,9 @@ class CharField(WritableField):
|
||||||
self.validators.append(validators.MaxLengthValidator(max_length))
|
self.validators.append(validators.MaxLengthValidator(max_length))
|
||||||
|
|
||||||
def from_native(self, value):
|
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 value
|
||||||
return smart_text(value)
|
return smart_text(value)
|
||||||
|
|
||||||
|
|
|
@ -804,6 +804,10 @@ class ModelSerializer(Serializer):
|
||||||
issubclass(model_field.__class__, models.PositiveSmallIntegerField):
|
issubclass(model_field.__class__, models.PositiveSmallIntegerField):
|
||||||
kwargs['min_value'] = 0
|
kwargs['min_value'] = 0
|
||||||
|
|
||||||
|
if model_field.null and \
|
||||||
|
issubclass(model_field.__class__, (models.CharField, models.TextField)):
|
||||||
|
kwargs['allow_none'] = True
|
||||||
|
|
||||||
attribute_dict = {
|
attribute_dict = {
|
||||||
models.CharField: ['max_length'],
|
models.CharField: ['max_length'],
|
||||||
models.CommaSeparatedIntegerField: ['max_length'],
|
models.CommaSeparatedIntegerField: ['max_length'],
|
||||||
|
|
|
@ -1124,6 +1124,20 @@ class BlankFieldTests(TestCase):
|
||||||
serializer = self.model_serializer_class(data={})
|
serializer = self.model_serializer_class(data={})
|
||||||
self.assertEqual(serializer.is_valid(), True)
|
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
|
#test for issue #460
|
||||||
class SerializerPickleTests(TestCase):
|
class SerializerPickleTests(TestCase):
|
||||||
|
@ -1490,6 +1504,7 @@ class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
|
||||||
image_field = models.ImageField(max_length=1024, blank=True)
|
image_field = models.ImageField(max_length=1024, blank=True)
|
||||||
slug_field = models.SlugField(max_length=1024, blank=True)
|
slug_field = models.SlugField(max_length=1024, blank=True)
|
||||||
url_field = models.URLField(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 AMOAFSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -1522,6 +1537,10 @@ class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
|
||||||
'url_field': [
|
'url_field': [
|
||||||
('max_length', 1024),
|
('max_length', 1024),
|
||||||
],
|
],
|
||||||
|
'nullable_char_field': [
|
||||||
|
('max_length', 1024),
|
||||||
|
('allow_none', True),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
def field_test(self, field):
|
def field_test(self, field):
|
||||||
|
@ -1558,6 +1577,9 @@ class AttributeMappingOnAutogeneratedFieldsTests(TestCase):
|
||||||
def test_url_field(self):
|
def test_url_field(self):
|
||||||
self.field_test('url_field')
|
self.field_test('url_field')
|
||||||
|
|
||||||
|
def test_nullable_char_field(self):
|
||||||
|
self.field_test('nullable_char_field')
|
||||||
|
|
||||||
|
|
||||||
class DefaultValuesOnAutogeneratedFieldsTests(TestCase):
|
class DefaultValuesOnAutogeneratedFieldsTests(TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user