Checklist
Steps to reproduce
- For example, we have serializer like this:
class CommunitySerializer(Serializer):
colors = ListField(allow_null=True, child=CharField(label='Colors', max_length=7), required=False)
- We submit partial update encoded as form data:
test_client.patch('/communities/1/', {'colors[0]': '#ffffff', 'colors[1]': '#000000'}, 'multipart')
- This will encode request body like this:
--BoUnDaRyStRiNg
Content-Disposition: form-data; name="colors[0]"
#000000
--BoUnDaRyStRiNg
Content-Disposition: form-data; name="colors[1]"
#ffffff
--BoUnDaRyStRiNg--
Expected behavior
validated_data should contain colors value parsed into a list with the respected order.
Actual behavior
validated_data is an empty dictionary.
Explanation
ListField.get_value checks that field is present with in statement:
|
if self.field_name not in dictionary: |
- Since
field_name does not match submitted keys, method checks in this is a partial update
|
if getattr(self.root, 'partial', False): |
- Since this is also true, the method returns an empty marker.
- Field name with ordered marker does not check to present.
Alternative
We can submit the partial update with list fields unordered:
test_client.patch('/communities/1/', {'colors': ['#ffffff', '#000000']}, 'multipart')
Form data will look like this
--BoUnDaRyStRiNg
Content-Disposition: form-data; name="colors"
#000000
--BoUnDaRyStRiNg
Content-Disposition: form-data; name="colors"
#ffffff
--BoUnDaRyStRiNg--
So in statement will evaluate to true, so dictionary will be processed by HTML parser.
|
return html.parse_html_list(dictionary, prefix=self.field_name, default=empty) |
But this format does not guarantee items order in the list, so we can not use it for things like gradients.
Full update and create methods do not have this problem because partial check evaluates to false.
We can't use full updates because we have two file fields near. We don't want to force the user to upload two files just to change string values in the same request.
P.S.
If you think we should solve this, I'll be able to make a PR for it.
Checklist
masterbranch of Django REST framework.Steps to reproduce
Expected behavior
validated_datashould contain colors value parsed into a list with the respected order.Actual behavior
validated_datais an empty dictionary.Explanation
ListField.get_valuechecks that field is present withinstatement:django-rest-framework/rest_framework/fields.py
Line 1639 in ed6340e
field_namedoes not match submitted keys, method checks in this is a partial updatedjango-rest-framework/rest_framework/fields.py
Line 1640 in ed6340e
django-rest-framework/rest_framework/fields.py
Line 1641 in ed6340e
Alternative
We can submit the partial update with list fields unordered:
Form data will look like this
So
instatement will evaluate to true, so dictionary will be processed by HTML parser.django-rest-framework/rest_framework/fields.py
Line 1649 in ed6340e
But this format does not guarantee items order in the list, so we can not use it for things like gradients.
Full update and create methods do not have this problem because partial check evaluates to false.
We can't use full updates because we have two file fields near. We don't want to force the user to upload two files just to change string values in the same request.
P.S.
If you think we should solve this, I'll be able to make a PR for it.