简体   繁体   English

将方法添加到 ModelViewset Endpoint 中,无需调用 URL 中的方法名称

[英]Add method to ModelViewset Endpoint without having to call the method name in the URL

I have two separate endpoints that "accepts" and "declines" each applicant on the system respectively.我有两个单独的端点,分别“接受”和“拒绝”系统上的每个申请人。

Endpoint #1:端点#1:

...api/v1/applicants/{ID}/accept

Endpoint #2:端点#2:

...api/v1/applicants/{ID}/decline

Now, I'm refactoring and trying to combine the Endpoints into one, such that the following URL can be used to accept and decline an applicant, while maintaining :现在,我正在重构并尝试将端点合并为一个,以便可以使用以下 URL接受拒绝申请人,同时保持:

...api/v1/applicants/{ID}/

The purpose of doing this is to conform the endpoints to REST methodologies.这样做的目的是使端点符合 REST 方法。

WHAT I TRIED:我试过的:

I tried creating a hidden method [starting with underscore - eg: _someFunction() using a PUT request method].我尝试创建一个隐藏的方法 [以下划线开头 - 例如:_someFunction() 使用 PUT 请求方法]。 This didn't work.这没有用。

I know I could also do it through the serializers.py file but don't know how as I haven't seen an example online.我知道我也可以通过serializers.py文件来做到这一点,但不知道怎么做,因为我还没有在网上看到一个例子。

Here is the accept class.这是接受类。 The decline is similar with minor changes:下降幅度类似,但有细微的变化:

@action(detail=True, methods=['put'])
def accept(self, request, pk):
    data = request.data

    if request.user.user_type == "2":

        if Applicant.objects.filter(id=pk).exists():
            applicant = Applicant.objects.get(id=pk)
            if applicant.status == '1':
                applicant.status = '2'
                applicant.save()

                # Hash the ID of the particular applicant so it can be used for verification
                # make this a function during refactoring

                hashids = Hashids(salt=HASH_SALT, min_length=16)
                hashid = hashids.encode(applicant.id)

                # send email with the link to the applicant
                # make this a function too

                SENDER="xxx@example.com"
                SUBJECT="Congratulations, you've been accepted!"
                MESSAGE = """

                    Hello {}, \n                    
                    Your application as a Journalist on example.com was accepted.\n 
                    Copy your OTP: {} and Click here "https://example.com/verify-otp/ to enter it.\n
                    Cheers!
                    """.format(applicant.first_name, hashid)

                send_mail(SUBJECT, MESSAGE, SENDER, [applicant.email], fail_silently=False)

                # generate a response object
                queryset = applicant
                serializer = ApplicantSerializer(queryset)
                return Response(jsend.success({'applicants':serializer.data}))

            else:
                return Response((jsend.error("Cannot perform such action for this applicant")), status=status.HTTP_400_BAD_REQUEST)

        else:
            return Response((jsend.error('Cannot find an applicant with ID of {}'.format(pk))), status=status.HTTP_404_NOT_FOUND)
    else:
        return Response((jsend.error("You are not authorized to perform this action")), status=status.HTTP_403_FORBIDDEN)

You can override the perform_update() or update() of the ModelViewSet for example using perform_update:例如,您可以使用 perform_update 覆盖 ModelViewSet 的 perform_update() 或 update() :

 def perform_update(self, serializer):
    applicant = self.get_object()
    if applicant.status == '1':
            serializer.save(status='2')
    #rest of your logic
    serializer.save()

Hope it helps.希望能帮助到你。 Note you can get the request inside perform_update like this:请注意,您可以像这样在 perform_update 中获取请求:

self.request

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM