Fix parsing multipart data using a nested serializer with list by lrnt · Pull Request #3820 · encode/django-rest-framework (original) (raw)

Parsing multipart data using a nested serializer with a list can result in incorrect behavior. If the list contains more than one item, only the last item will be saved.

Here is an example:

class NestedSerializer(serializers.Serializer): example = serializers.MultipleChoiceField(choices=[1, 2, 3])

class TestSerializer(serializers.Serializer): nested = NestedSerializer()

When you send the following data formatted as JSON everything will be fine:

{ 'nested': { 'example': [1, 2], } }

--->

{ 'nested': { 'example': [1, 2], } }

However, when you send the same data formatted as multipart data the serialized object will only take the last element of the list:

{ 'nested.example': [1, 2] }

--->

{ 'nested' { 'example': 2, } }

The bug is situated in parse_html_dict(dictionary, prefix='') in rest_framework.utils.html. This function takes and returns a new MultiValueDict. A key in a MultiValueDict can have multiple values, this is how a list is represented. When accessing a key in a MultiValueDict only the last element of the list is returned.

This can be easily solved by using .getlist() and .setlist() when getting and setting the value of the MultiValueDict.

Closes #3710.