Search code examples
pythondjangooopdjango-rest-frameworkmixins

Attempting to override update method in django rest framework to return entire queryset after update


I am attempting to override the update method for a put request in django rest framework. Instead of returning just the updated object. I want it to return the entire queryset including the updated object. For the use case I am working on, its just easier.

Starting from the top.

I am using Django Rest Frameworks Generics.

class SearchCityDetail(RetrieveUpdateDestroyAPIView):
    queryset = SearchCity.objects.all()
    serializer_class = SearchCitySerializer

I override the classes PUT method and inherent from my custom mixin.

class SearchCityDetail(RetrieveUpdateDestroyAPIView, UpdateReturnAll):
queryset = SearchCity.objects.all()
serializer_class = SearchCitySerializer

def put(self, request, *args, **kwargs):
    return self.updatereturnall(self,request, *args, **kwargs)

the custom mixin looks like this (my custom added code which differs from the normal update code had the commment #Custom Code above it:

    from rest_framework import status
    from rest_framework.response import Response
    from rest_framework.settings import api_settings
    from rest_framework.mixins import UpdateModelMixin
    """
       Update a model instance and return all.
   """
#Custom Code
class UpdateReturnAll(UpdateModelMixin):

    #custom name normally just update
    def updatereturnall(self, request,  model, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        #all objects and all serializer is custom code 
        allobjects = self.get_queryset(self)
        allserializer = self.get_serializer(allobjects, many=True)

        return Response(allserializer.data)


    def perform_update(self, serializer):
        serializer.save()


    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)

The self.get_queryset and the self.get_serializer are functions defined in the GenericAPIView which RetrieveUpdateDestroyAPIView inherents from. And since I am inheriting the UpdateReturnAll into the SearchCityDetail class the two methods should be available to the UpdateReturnALL

that is my understanding.

I am currently getting an error and status code 500

the error being: AttributeError: 'SearchCityDetail' object has no attribute 'data'

what am I doing wrong?


Solution

  • It should be:

    class SearchCityDetail(RetrieveUpdateDestroyAPIView, UpdateReturnAll):
        queryset = SearchCity.objects.all()
        serializer_class = SearchCitySerializer
    
        def put(self, request, *args, **kwargs):
            return self.updatereturnall(request, *args, **kwargs)
    

    Instead of return self.updatereturnall(self,request, *args, **kwargs).

    Don't need to pass self argument explicit when call self.updatereturnall method, Python do it for you.