mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	Merge pull request #3415 from adamsc64/issue_2761
Fixed #2761 - ListField truncation on HTTP PATCH
This commit is contained in:
		
						commit
						f2c65512c6
					
				| 
						 | 
					@ -1265,14 +1265,13 @@ class MultipleChoiceField(ChoiceField):
 | 
				
			||||||
        super(MultipleChoiceField, self).__init__(*args, **kwargs)
 | 
					        super(MultipleChoiceField, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_value(self, dictionary):
 | 
					    def get_value(self, dictionary):
 | 
				
			||||||
 | 
					        if self.field_name not in dictionary:
 | 
				
			||||||
 | 
					            if getattr(self.root, 'partial', False):
 | 
				
			||||||
 | 
					                return empty
 | 
				
			||||||
        # We override the default field access in order to support
 | 
					        # We override the default field access in order to support
 | 
				
			||||||
        # lists in HTML forms.
 | 
					        # lists in HTML forms.
 | 
				
			||||||
        if html.is_html_input(dictionary):
 | 
					        if html.is_html_input(dictionary):
 | 
				
			||||||
            ret = dictionary.getlist(self.field_name)
 | 
					            return dictionary.getlist(self.field_name)
 | 
				
			||||||
            if getattr(self.root, 'partial', False) and not ret:
 | 
					 | 
				
			||||||
                ret = empty
 | 
					 | 
				
			||||||
            return ret
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return dictionary.get(self.field_name, empty)
 | 
					        return dictionary.get(self.field_name, empty)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_internal_value(self, data):
 | 
					    def to_internal_value(self, data):
 | 
				
			||||||
| 
						 | 
					@ -1419,6 +1418,9 @@ class ListField(Field):
 | 
				
			||||||
        self.child.bind(field_name='', parent=self)
 | 
					        self.child.bind(field_name='', parent=self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_value(self, dictionary):
 | 
					    def get_value(self, dictionary):
 | 
				
			||||||
 | 
					        if self.field_name not in dictionary:
 | 
				
			||||||
 | 
					            if getattr(self.root, 'partial', False):
 | 
				
			||||||
 | 
					                return empty
 | 
				
			||||||
        # We override the default field access in order to support
 | 
					        # We override the default field access in order to support
 | 
				
			||||||
        # lists in HTML forms.
 | 
					        # lists in HTML forms.
 | 
				
			||||||
        if html.is_html_input(dictionary):
 | 
					        if html.is_html_input(dictionary):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -289,3 +289,32 @@ class TestListSerializerClass:
 | 
				
			||||||
        serializer = TestSerializer(data=[], many=True)
 | 
					        serializer = TestSerializer(data=[], many=True)
 | 
				
			||||||
        assert not serializer.is_valid()
 | 
					        assert not serializer.is_valid()
 | 
				
			||||||
        assert serializer.errors == {'non_field_errors': ['Non field error']}
 | 
					        assert serializer.errors == {'non_field_errors': ['Non field error']}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestSerializerPartialUsage:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    When not submitting key for list fields or multiple choice, partial
 | 
				
			||||||
 | 
					    serialization should result in an empty state (key not there), not
 | 
				
			||||||
 | 
					    an empty list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Regression test for Github issue #2761.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def test_partial_listfield(self):
 | 
				
			||||||
 | 
					        class ListSerializer(serializers.Serializer):
 | 
				
			||||||
 | 
					            listdata = serializers.ListField()
 | 
				
			||||||
 | 
					        serializer = ListSerializer(data=MultiValueDict(), partial=True)
 | 
				
			||||||
 | 
					        result = serializer.to_internal_value(data={})
 | 
				
			||||||
 | 
					        assert "listdata" not in result
 | 
				
			||||||
 | 
					        assert serializer.is_valid()
 | 
				
			||||||
 | 
					        assert serializer.validated_data == {}
 | 
				
			||||||
 | 
					        assert serializer.errors == {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_partial_multiplechoice(self):
 | 
				
			||||||
 | 
					        class MultipleChoiceSerializer(serializers.Serializer):
 | 
				
			||||||
 | 
					            multiplechoice = serializers.MultipleChoiceField(choices=[1, 2, 3])
 | 
				
			||||||
 | 
					        serializer = MultipleChoiceSerializer(data=MultiValueDict(), partial=True)
 | 
				
			||||||
 | 
					        result = serializer.to_internal_value(data={})
 | 
				
			||||||
 | 
					        assert "multiplechoice" not in result
 | 
				
			||||||
 | 
					        assert serializer.is_valid()
 | 
				
			||||||
 | 
					        assert serializer.validated_data == {}
 | 
				
			||||||
 | 
					        assert serializer.errors == {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user