mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 01:47:59 +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