Django REST框架:基于查询字符串参数的update()

时间:2021-12-09 03:30:02

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?

是否可以修改ViewSet的update()函数,以基于查询字符串参数而不是URL资源名或请求体进行更新?

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.

并在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.

我不太确定该如何继续。我希望尽可能多地重用mixin中的update()函数。UpdateModelMixin越好。任何帮助都是感激。

1 个解决方案

#1


1  

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:

假设您想使用相同的url进行列表和检索实体的详细信息,区分url参数job-def-id的存在,这里有一个疯狂的想法:

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

我还没试过。我在这里查看了get_object和mixin的源代码

#1


1  

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:

假设您想使用相同的url进行列表和检索实体的详细信息,区分url参数job-def-id的存在,这里有一个疯狂的想法:

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

我还没试过。我在这里查看了get_object和mixin的源代码