django - How to update a single column on a single row? -


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.