Description
Checklist
- I have verified that that issue exists against the
master
branch of Django REST framework. - I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
- [?] This is not a usage question. (Those should be directed to the discussion group instead.)
- This cannot be dealt with as a third party library. (We prefer new functionality to be in the form of third party libraries where possible.)
- I have reduced the issue to the simplest possible case.
- I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.)
Steps to reproduce
I'm trying to implement a bulk update -- The django rest framework bulk update project seems abandoned, and has a bug that I think is the same as my implementation (I'm trying to do a minimal implementation just for my project and not be dependent on the other one.)
I suspect it's a bug that came up with a recent version of drf3.
The conversation in the bug proposes subclassing the ListSerializer and rewriting to_internal_value
, copying the code from the original implementation -- inserting this code into the method:
for item in data:
try:
# Code that was inserted
self.child.instance = self.instance.get(id=item['id'])
self.child.initial_data = item
# Until here
validated = self.child.run_validation(item)
The issue comes down to the internals of drf passing the list as the instance in exclude_current_instance().
Here's how I started implementing mine:
class _MyRouter(routers.DefaultRouter):
include_root_view = False
include_format_suffixes = False
def __init__(self, *args, **kwargs):
self.routes = copy.deepcopy(self.routes)
for route in self.routes:
if isinstance(route, routers.Route) and not route.detail:
route.mapping.update({
'put': 'bulk_update',
})
break
super(_MyRouter, self).__init__(*args, **kwargs)
I then implemented bulk_update
in my viewset - this is just the beginning of it for proof of concept:
def bulk_update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
assert not partial
serializer = self.get_serializer(
self.filter_queryset(self.get_queryset()),
data=request.data,
many=True,
partial=partial,
)
# import pdb; pdb.set_trace()
serializer.is_valid(raise_exception=True)
Stepping over is_valid()
raises the AttributeError: "'QuerySet' object has no attribute 'pk'"
I'm reluctant to go and just copy a bunch of code from drf into a subclass -- surely it will break in the future.
Expected behavior
I'm hoping there is already a supported way for doing this, and if not, I'm posting this in hope it's a use case you want to consider supporting (not directly the bulk update itself, but the underlying problem of the list serializer) so that bulk updates would be easier to implement outside the project.
Actual behavior
Stepping into is_valid()
eventually raises the AttributeError: "'QuerySet' object has no attribute 'pk'"