django-rest-framework-bulk
django-rest-framework-bulk copied to clipboard
Key error 'id' when doing PUT request
[DESCRIPTION]
When making a PUT request to a BulkModelViewSet, using a simple DRF ModelSerializer with all fields automatically generated - no field specified by hand -and with list_serializer_class attribute being BulkListSerializer the application crashes at this line and raises a KeyError for 'id' key.
[REASON]
When DRF ListSerializer passes validated_data to the update() method the given validated_data don't contain the id of the object.
[FIX]
DRF don't return id in validated_data anymore unless the field is explicitly declared in the serializer (id = serializers.IntegerField()) so you have to do that in order for it to work. I don't believe we should add it to DRF-bulk BulkListSerializer though, since pk might not be the id field, what do you think? Raising an exception if the 'id' key is not in validated_data might be a better solution.
[ENVIRONMENT] - Debian GNU/Linux 8 (8.2) - Django Version: 1.5.6 - Django-rest-framework Version: 3.2.4 - Python Version: 2.7.8
[TRACEBACK]
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
77. return view_func(*args, **kwargs)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
87. return self.dispatch(request, *args, **kwargs)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
466. response = self.handle_exception(exc)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
463. response = handler(request, *args, **kwargs)
File "/home/adelaby/Development/contexte-site/contexte/libs/utils/views/mixins.py" in bulk_update
42. self.perform_bulk_update(serializer)
File "/home/adelaby/Development/contexte-site/contexte/apps/users/views/rest.py" in perform_bulk_update
131. super(UsersViewSet, self).perform_bulk_update(serializer)
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/mixins.py" in perform_bulk_update
85. return self.perform_update(serializer)
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/mixins.py" in perform_update
82. serializer.save()
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/serializers.py" in save
643. self.instance = self.update(self.instance, validated_data)
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/serializers.py" in update
43. for i in all_validated_data
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/serializers.py" in <dictcomp>
43. for i in all_validated_data
from the docs:
- DRF3 removes read-only fields from
serializer.validated_data. As a result, it is impossible to correlate eachvalidated_datainListSerializerwith a model instance to update sincevalidated_datawill be missing the model primary key since that is a read-only field. To deal with that, you must useBulkSerializerMixinmixin in your serializer class which will add the model primary key field back to thevalidated_data.