Kevin Y
Kevin Y

Reputation: 45

Django REST Framework : update() based on query string parameter

Is it possible to modify a ViewSet's update() function to update based on a query string parameter instead of a URL resource name or the request body?

For example, I want trigger something like this:

payload = {'field' : '2'}
r = requests.put("http://127.0.0.1:9876/job-defs?job-def-id=2", data=payload)

and have this update my field when job-def-id = 2.

What I have so far is this:

class JobDefinitionsViewSet(mixins.ListModelMixin,
                        mixins.CreateModelMixin,
                        mixins.UpdateModelMixin,
                        mixins.DestroyModelMixin,
                        viewsets.GenericViewSet):

    serializer_class = JobDefinitionsSerializer

    def update(self, request, pk=None):
        job_def_id = self.request.query_params.get('job-def-id', None)
        super(JobDefinitionsViewSet, self).update(self, request, pk=job_def_id)

    ...
    # other unrelated code
    ...

I'm not too sure how to continue. I want to reuse as much as the update() function from mixins.UpdateModelMixin as possible. Any help is appreciated.

Upvotes: 2

Views: 3048

Answers (1)

Pynchia
Pynchia

Reputation: 11580

Assuming you want to use the same url for listing and for retrieving the details of the entity, discriminating on the presence of the url parameter job-def-id, here is a crazy idea:

class JobDefinitionsAllInOneView(mixins.UpdateModelMixin,
                                 mixins.DestroyModelMixin,
                                 mixins.ListModelMixin,
                                 mixins.CreateModelMixin,
                                 generics.GenericAPIView):

    queryset = JobDefinitions.objects.all()
    serializer_class = JobDefinitionsSerializer

    def get_object(self):
        job_def_id = self.request.query_params.get('job-def-id', None)
        if job_def_id is not None:
            self.kwargs['pk'] = job_def_id
        return super(JobDefinitionsAllInOneView, self).get_object()

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

    def get(self, request, *args, **kwargs):
        job_def_id = self.request.query_params.get('job-def-id', None)
        if job_def_id is not None:
            # return the details
            return self.retrieve(request, *args, **kwargs)
        else:
            # return a list
            return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def patch(self, request, *args, **kwargs):
        return self.partial_update(self, request, *args, **kwargs)
    def delete(self, request, *args, **kwargs):
        return self.destroy(self, request, *args, **kwargs)

I haven't tried it yet. I had a look at the source code here for get_object and here for the mixins

Upvotes: 1

Related Questions