Home > front end >  Get post() function from the view function returned by resolve()
Get post() function from the view function returned by resolve()

Time:03-08

I defined a class based on rest_framework.views.APIView and added it as a view to some url. For example like:

from rest_framework.views import APIView
from rest_framework.response import Response
from django.urls import path

class MyApi(APIView):

    def post(self, request):
        # Do something with the request
        print(request.data)
        return Response(status=200)


path('my-url', MyApi.as_view())

In another file, I want to access the post() function of that class, but I only know the url. So I use the django.urls.resolve() function to get the view function.

from django.urls import resolve
view, args, kwargs = resolve(url)

However, I don't want to obtain the view function, but the underlying post() function that I defined in the API-Class.

Is there any option to get that function while only knowing the url?

I want to avoid building a lookup for every possible url.

CodePudding user response:

rest_framework.views.APIView calls one of its methods based on the requests method. so the function cannot be obtained from the request URL only. it needs both URL and request method. for example, if you send a POST request to example/, it calls the post method of your APIView. and if you call the same URL with the GET method, it calls the get method of your view.

from rest_framework.views.APIView source code:

# Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

so we can do the same.

first, get the view from the resolve function:

from django.urls import resolve
view, args, kwargs = resolve(request.URL)

then, obtain the handler function from view:

if request.method.lower() in view.http_method_names:
    handler = getattr(view, request.method.lower(),None)
else:
    handler = None
  • Related