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.