mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	Merge pull request #2311 from tomchristie/allow-empty-text-or-boolean-html-input-if-not-required
Fixes for behavior with empty HTML fields.
This commit is contained in:
		
						commit
						22ffeafc3e
					
				| 
						 | 
				
			
			@ -184,12 +184,10 @@ class Field(object):
 | 
			
		|||
        self.style = {} if style is None else style
 | 
			
		||||
        self.allow_null = allow_null
 | 
			
		||||
 | 
			
		||||
        if allow_null and self.default_empty_html is empty:
 | 
			
		||||
            # HTML input cannot represent `None` values, so we need to
 | 
			
		||||
            # forcibly coerce empty HTML values to `None` if `allow_null=True`.
 | 
			
		||||
            self.default_empty_html = None
 | 
			
		||||
 | 
			
		||||
        if default is not empty:
 | 
			
		||||
        if self.default_empty_html is not empty:
 | 
			
		||||
            if not required:
 | 
			
		||||
                self.default_empty_html = empty
 | 
			
		||||
            elif default is not empty:
 | 
			
		||||
                self.default_empty_html = default
 | 
			
		||||
 | 
			
		||||
        if validators is not None:
 | 
			
		||||
| 
						 | 
				
			
			@ -562,6 +560,11 @@ class CharField(Field):
 | 
			
		|||
            message = self.error_messages['min_length'].format(min_length=min_length)
 | 
			
		||||
            self.validators.append(MinLengthValidator(min_length, message=message))
 | 
			
		||||
 | 
			
		||||
        if self.allow_null and (not self.allow_blank) and (self.default is empty):
 | 
			
		||||
            # HTML input cannot represent `None` values, so we need to
 | 
			
		||||
            # forcibly coerce empty HTML values to `None` if `allow_null=True`.
 | 
			
		||||
            self.default_empty_html = None
 | 
			
		||||
 | 
			
		||||
    def run_validation(self, data=empty):
 | 
			
		||||
        # Test for the empty string here so that it does not get validated,
 | 
			
		||||
        # and so that subclasses do not need to handle it explicitly
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -215,25 +215,47 @@ class TestBooleanHTMLInput:
 | 
			
		|||
        assert serializer.validated_data == {'archived': False}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MockHTMLDict(dict):
 | 
			
		||||
    """
 | 
			
		||||
    This class mocks up a dictionary like object, that behaves
 | 
			
		||||
    as if it was returned for multipart or urlencoded data.
 | 
			
		||||
    """
 | 
			
		||||
    getlist = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestCharHTMLInput:
 | 
			
		||||
    def setup(self):
 | 
			
		||||
    def test_empty_html_checkbox(self):
 | 
			
		||||
        class TestSerializer(serializers.Serializer):
 | 
			
		||||
            message = serializers.CharField(default='happy')
 | 
			
		||||
        self.Serializer = TestSerializer
 | 
			
		||||
 | 
			
		||||
    def test_empty_html_checkbox(self):
 | 
			
		||||
        """
 | 
			
		||||
        HTML checkboxes do not send any value, but should be treated
 | 
			
		||||
        as `False` by BooleanField.
 | 
			
		||||
        """
 | 
			
		||||
        # This class mocks up a dictionary like object, that behaves
 | 
			
		||||
        # as if it was returned for multipart or urlencoded data.
 | 
			
		||||
        class MockHTMLDict(dict):
 | 
			
		||||
            getlist = None
 | 
			
		||||
        serializer = self.Serializer(data=MockHTMLDict())
 | 
			
		||||
        serializer = TestSerializer(data=MockHTMLDict())
 | 
			
		||||
        assert serializer.is_valid()
 | 
			
		||||
        assert serializer.validated_data == {'message': 'happy'}
 | 
			
		||||
 | 
			
		||||
    def test_empty_html_checkbox_allow_null(self):
 | 
			
		||||
        class TestSerializer(serializers.Serializer):
 | 
			
		||||
            message = serializers.CharField(allow_null=True)
 | 
			
		||||
 | 
			
		||||
        serializer = TestSerializer(data=MockHTMLDict())
 | 
			
		||||
        assert serializer.is_valid()
 | 
			
		||||
        assert serializer.validated_data == {'message': None}
 | 
			
		||||
 | 
			
		||||
    def test_empty_html_checkbox_allow_null_allow_blank(self):
 | 
			
		||||
        class TestSerializer(serializers.Serializer):
 | 
			
		||||
            message = serializers.CharField(allow_null=True, allow_blank=True)
 | 
			
		||||
 | 
			
		||||
        serializer = TestSerializer(data=MockHTMLDict({}))
 | 
			
		||||
        assert serializer.is_valid()
 | 
			
		||||
        assert serializer.validated_data == {'message': ''}
 | 
			
		||||
 | 
			
		||||
    def test_empty_html_required_false(self):
 | 
			
		||||
        class TestSerializer(serializers.Serializer):
 | 
			
		||||
            message = serializers.CharField(required=False)
 | 
			
		||||
 | 
			
		||||
        serializer = TestSerializer(data=MockHTMLDict())
 | 
			
		||||
        assert serializer.is_valid()
 | 
			
		||||
        assert serializer.validated_data == {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestCreateOnlyDefault:
 | 
			
		||||
    def setup(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user