django-rest-framework-bulk icon indicating copy to clipboard operation
django-rest-framework-bulk copied to clipboard

Key error 'id' when doing PUT request

Open adelaby opened this issue 10 years ago • 1 comments

[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

adelaby avatar Oct 21 '15 14:10 adelaby

from the docs:

  • DRF3 removes read-only fields from serializer.validated_data. As a result, it is impossible to correlate each validated_data in ListSerializer with a model instance to update since validated_data will be missing the model primary key since that is a read-only field. To deal with that, you must use BulkSerializerMixin mixin in your serializer class which will add the model primary key field back to the validated_data.

Jcbobo avatar Nov 17 '15 08:11 Jcbobo