i'm trying write simple update view django rest application, cannot figure out how it. i've gotten range of errors 403 500.
basically, have table 'foo' , want set 'active' field 'true' 'false'. here's view have currently:
class disablefoo(generics.updateapiview): permission_classes = (permissions.isauthenticated,) serializer_class = fooserializer queryset = foo.objects.all() def perform_update(self, serializer): queryset = foo.objects.filter(pk = self.request.data['id']) queryset.update(active = false) however, results in assertionerror:
expected view disablefoo called url keyword argument named "pk". fix url conf, or set '.lookup_field' attribute on view correctly.
you should not send id of row want update request.data within url.
so if hitting right like:
/api/foo/
try
/api/foo/<id>/
of course won't enough. should consider few more things.
you hooking on perform_update method. that's not correct. perform_update called in order update whole object serializer.save() , therefore called when serializer.is_valid().
this means have send valid foo object. that's not want. need update single field of foo object. right approach here use partial_update. partial_update used when make patch request /api/foo/<id>/
so if send patch request /api/foo/<id>/ active=0 inside request.data drf update object automatically without further code changes. using
class disablefoo(generics.updateapiview): permission_classes = (permissions.isauthenticated,) serializer_class = fooserializer queryset = foo.objects.all() but expose model fields update. can override partial_update method so:
def partial_update(self, request, *args, **kwargs): instance = self.get_object() instance.active = false instance.save(update_fields=['active']) return response() another approach
drf support creation of extra extra-actions via @detail_route , @list_route decorators.
you can use @detail_route create custom disable action. consider following peace of code:
class fooviewset(viewsets.genericviewset): queryset = foo.objects.all() serializer_class = fooserializer @detail_route(methods=['post']) def disable(self, request, pk=none): instance = self.get_object() instance.active = false instance.save(update_fields=['active']) return response('done') making post request /api/foo/<id>/disable call disable method wrote , disable foo instance under <id>.
this way can escape requirement use patch request method.