Apiview of DRF
When we write CBV in Django, we inherit view, while rest_framework inherits apiview. What are the differences between them ~~~
urlpatterns = [ url(r ‘^book$‘ , BookView.as_view()), url(r ‘^book/(?P<id>\d+)$‘ , BookEditView.as_view()), ] |
We can see that the as_view () method is called both in view and apiview at the beginning ~~ Let's look at the source code ~~
We can see that apiview inherits the view and executes the as_view () method in the view. Finally, the view is returned, and csrf authentication is removed after being wrapped in the csrf_exempt () method.
Let's take a look at what the as_view () method in the view has done ~
We see ~ The as_view method in view returns the view function, and the view function executes the self. Dispatch () method ~~ However, the dispatch method here should be in our apiview ~~
Let's go to initialize_request to see what is assigned to the request, and assign the value to self. request, that is, what request. XXX is used in the view ~~
We can see that this method returns the instance object of the request class ~~ Note that the first request parameter in this request class is the original request when we go through Django ~
We can see that this request class assigned the original request to self. _ request, that is, the future _ request is our old request, and the new request is our request class ~~
Where are the data requested After inheriting apiview ~~
After we use the rest_framework framework, our request is a re-encapsulated request class ~
Request. query_params stores the parameters of our GET request.
Request. data stores all our data, including post requests and put and patch requests ~~~
Compared with the original Django request, our current request is simpler and clearer ~~~
Now we know the differences between apiview and view ~~ Of course ~~ We will also talk about it later ~~
The view we write may add, delete, modify, and query multiple tables, which leads to a lot of repeated code in our view ~~
Then we try to encapsulate it ~~
First Encapsulation
Class bookview (apiview): def get (self, request): query_set = book. objects. all () book_ser = bookserializer (query_set, response = true) return response (book_ser.data) def post (self, request): query_set = request. data book_ser = bookserializer (Data = query_set) If response (): book_ser.save () return response (response) else: return response (book_ser.errors) Class bookeditview (apiview): def get (self, request, ID): query_set = book. objects. filter (ID = ID ). first () book_ser = bookserializer (query_set) return response (book_ser.data) def patch (self, request, ID): query_set = book. objects. filter (ID = ID ). first () book_ser = bookserializer (query_set, Data = request. data, partial = true) If book_ser.is_valid (): book_ser.save () return response (response) else: return response (book_ser.errors) def Delete (self, request, ID): query_set = book. objects. filter (ID = ID ). first () If query_set: query_set.delete () return response ("") else: return response ("the deleted book does not exist ")
Apiview View
Class genericapiview (apiview): queryset = none serializer_class = none def get_queryset (Self): return self. queryset. all () def get_serializer (self, * ARGs, ** kwargs): return self. serializer_class (* ARGs, ** kwargs) Class listmodelmixin (object): def list (self, request, * ARGs, ** kwargs): queryset = self. get_queryset () serializer = self. get_serializer (queryset, response = true) return response (serializer. data) Class createmodelmixin (object): def create (self, request, * ARGs, ** kwargs): serializer = self. get_serializer (Data = request. data) If serializer. is_valid (): serializer. save () return response (serializer. validated_data) else: return response (serializer. errors) Class retrievemodelmixin (object): def retrieve (self, request, ID, * ARGs, ** kwargs): book_obj = self. get_queryset (). filter (PK = ID ). first () book_ser = self. get_serializer (book_obj) return response (book_ser.data) Class updatemodelmixin (object): def Update (self, request, ID, * ARGs, ** kwargs): book_obj = self. get_queryset (). filter (PK = ID ). first () book_ser = self. get_serializer (book_obj, Data = request. data, partial = true) If book_ser.is_valid (): book_ser.save () return response (response) else: return response (book_ser.errors) Class destroymodelmixin (object): def destroy (self, request, request, ID, * ARGs, ** kwargs): queryset = self. get_queryset () Try: queryset. get (PK = ID ). delete () return response ("") failed t exception as E: return response ("error message ") # We extract the public part so that no matter how many tables are written, the addition, deletion, modification, and query operations become very simple # after this encapsulation, our view will become the class bookview (genericapiview, listmodelmixin, createmodelmixin): queryset = book. objects. all () serializer_class = bookserializer def get (self, request, * ARGs, ** kwargs): return self. list (request, * ARGs, ** kwargs) def post (self, request, * ARGs, ** kwargs): return self. create (request, * ARGs, ** kwargs) Class bookeditview (genericapiview, retrievemodelmixin, updatemodelmixin, destroymodelmixin): queryset = book. objects. all () serializer_class = bookserializer def get (self, request, ID, * ARGs, ** kwargs): return self. retrieve (request, ID, * ARGs, ** kwargs) def patch (self, request, ID, * ARGs, ** kwargs): return self. update (request, ID, * ARGs, ** kwargs) def destroy (self, request, ID, * ARGs, ** kwargs): return self. delete (request, ID, * ARGs, ** kwargs)
First Encapsulation
The encapsulated genericapiview includes classes that encapsulate each method. In fact, the framework has helped us encapsulate it ~~
We can directly inherit these classes ~~ To implement the above view ~~ But is there any simpler way ~ Let's encapsulate it again ~~
Second Encapsulation
# The inherited class we wrote above is too long ~~ Modify class listcreateapiview (genericapiview, listmodelmixin, createmodelmixin): passclass values (genericapiview, callback, updatemodelmixin, callback): passclass bookview (listcreateapiview): queryset = book. objects. all () serializer_class = bookserializer def get (self, request, * ARGs, ** kwargs): return self. list (request, * ARGs, ** kwargs) def post (self, request, * ARGs, ** kwargs): return self. create (request, * ARGs, ** kwargs) Class bookeditview (retrieveupdatedestroyapiview): queryset = book. objects. all () serializer_class = bookserializer def get (self, request, ID, * ARGs, ** kwargs): return self. retrieve (request, ID, * ARGs, ** kwargs) def patch (self, request, ID, * ARGs, ** kwargs): return self. update (request, ID, * ARGs, ** kwargs) def Delete (self, request, ID, * ARGs, ** kwargs): return self. delete (request, ID, * ARGs, ** kwargs)
Second Encapsulation
This time we just made inheritance a little simpler. It seems that there is no major progress ~~
Can we combine these two views into one ~~~ The Framework provides us with a route parameter passing method ~~
Let's take a look at viewsetmixin.
The default actions parameter is actually a parameter that can be passed through the route ~~~
The following loop ~ We can see that ~ The parameter to be passed is a field ~ Key should be our request method, and value should correspond to our processing method ~
In this way, each view does not need to write functions ~ Because it already corresponds to the Internally implemented Function ~
Third Encapsulation
urlpatterns = [ # url(r‘^book$‘, BookView.as_view()), # url(r‘^book/(?P<id>\d+)$‘, BookEditView.as_view()), url(r‘^book$‘, BookView.as_view({"get": "list", "post": "create"})), url(r‘^book/(?P<pk>\d+)$‘, BookView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})),]
URL. py
From rest_framework.viewsets import viewsetmixin # class bookview (viewsetmixin, listcreateapiview, retrieveupdatedestroyapiview): # queryset = book. objects. all () # serializer_class = bookserializer # If we define another class modelviewset (viewsetmixin, listcreateapiview, retrieveupdatedestroyapiview): passclass bookview (modelviewset): queryset = book. objects. all () serializer_class = bookserializer
Third Encapsulation
We only need to write two lines in the current view ~~~
In fact, all the views we write ~ The frameworks have been encapsulated for us ~
Note that ~~ View encapsulated by framework ~ The keyword parameter on our URL must use PK ~~ System Default ~~
Here is a picture of our inheritance order ~~~
DRF route
There are many parameters for route passing ~~ The framework has also been encapsulated for us ~
from .views import BookViewfrom rest_framework.routers import DefaultRouterrouter = DefaultRouter()router.register(r"book", BookView)urlpatterns = [ # url(r‘^book$‘, BookView.as_view()), # url(r‘^book/(?P<id>\d+)$‘, BookEditView.as_view()), # url(r‘^book$‘, BookView.as_view({"get": "list", "post": "create"})), # url(r‘^book/(?P<pk>\d+)$‘, BookView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})),]urlpatterns += router.urls
Routing
We can see that ~~ Through the framework, we can make the routing view very simple ~~
However, we still need to use apiview to write custom data ~~ When so many routes are not needed ~ Do not use this route to register ~~
In short ~~ Use everything as needed ~~~
DRF view and Routing