preface
Pinduoduo coupon https://m.fenfaw.net/ generally, after we finish serialization, we will start to write views. In drf, we generally use CBV, that is, class View. The most basic way is to use from rest_framework.views import APIView. APIView inherits from View. We will talk about the details of View later. This chapter describes the request lifecycle of drf
Pre preparation
Let's write a view class TestView first. The code is as follows:
from rest_framework.views import APIView from rest_framework.response import Response class TestView(APIView): def get(self, request, *args, **kwargs): return Response("drf get ok") def post(self, request, *args, **kwargs): return Response("drf post ok")
Note: the Response here must be the Response under drf, not the native HttpResponse or JsonResponse of Django, otherwise an error will occur
Then, in URLs Configure routing in py as follows
urlpatterns = [ path('test/', views.TestView.as_view(), name="Test"), ]
Then we visit http://127.0.0.1:8000/drf/test/ , the following style will appear, indicating that the request is successful
Then we use POST request to access in the interface tool, and the returned results are as follows:
"drf post ok"
The above two access methods have been successful. Next, we analyze the request process and principle
Request lifecycle analysis
First, let's see views. Com from the routing configuration TestView. as_view() calls as under the testview class view_ View method, but when we defined this method above, we did not override as_view () method, so as in the parent APIView will be called_ View method, the source code is as follows:
@classmethod def as_view(cls, **initkwargs): """ Store the original class on the view function. This allows us to discover information about the view when we do URL reverse lookups. Used for breadcrumb generation. """ # Determine whether queryset is a queryset object if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet): def force_evaluation(): raise RuntimeError( 'Do not evaluate the `.queryset` attribute directly, ' 'as the result will be cached and reused between requests. ' 'Use `.all()` or call `.get_queryset()` instead.' ) cls.queryset._fetch_all = force_evaluation # Call as of parent class_ View method view = super().as_view(**initkwargs) view.cls = cls view.initkwargs = initkwargs # Note: session based authentication is explicitly CSRF validated, # all other authentication is CSRF exempt. # csrf authentication disabled return csrf_exempt(view)
Through this line of code, view = super() as_view (* * initkwargs), you can know the as of APIView_ The view method also calls the as of the parent class view_ View method, the source code is as follows:
def as_view(cls, **initkwargs): """Main entry point for a request-response process.""" for key in initkwargs: if key in cls.http_method_names: raise TypeError("You tried to pass in the %s method name as a " "keyword argument to %s(). Don't do that." % (key, cls.__name__)) if not hasattr(cls, key): raise TypeError("%s() received an invalid keyword %r. as_view " "only accepts arguments that are already " "attributes of the class." % (cls.__name__, key)) def view(request, *args, **kwargs): self = cls(**initkwargs) # If there is a get attribute and there is no head attribute, then head is get if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get # Initializes properties shared by all view methods self.setup(request, *args, **kwargs) # If there is no request attribute, an exception is reported if not hasattr(self, 'request'): raise AttributeError( "%s instance has no 'request' attribute. Did you override " "setup() and forget to call super()?" % cls.__name__ ) # Return a 'dispatch' method return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch update_wrapper(view, cls.dispatch, assigned=()) return view
as_ The view method returns the view and the view returns the dispatch method. The dispatch method is also the dispatch method under APIView. The source code is as follows:
def dispatch(self, request, *args, **kwargs): """ `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ self.args = args self.kwargs = kwargs # Initialize the Request and return the Request object request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try: # Run any action that needs to occur before calling the method handler self.initial(request, *args, **kwargs) # Get the appropriate handler method # Get request method of request 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) except Exception as exc: # If an exception occurs before calling the method handler, an exception is run response = self.handle_exception(exc) # Returns a response response object self.response = self.finalize_response(request, response, *args, **kwargs) return self.response
dispatch returns a response response object, obtains the response result of the request, and returns it to the foreground
summary
- The url request takes the as of APIView_ View function
- As in APIView_ View calls the as of the parent class (django native)_ View, csrf authentication is also disabled
- As in the parent class_ The dispatch method in view requests the dispatch of APIView
- The task completion method is handed over to the view class function for processing, and the response result of the request is obtained and returned to the foreground