A review of drf request response
# 1 drf request
-Request object: data, query_params, others are the same as before, FILES
-Default: supports three encodings
-Local configuration: in view class
-from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
-parser_classes=[JSONParser]
-Global configuration:
REST_FRAMEWORK = {<!-- -->
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
],
}
- Use it globally, change it locally---》Just change the view class
# 2 drf response
-Response ---》Must inherit django’s native HTTPResponse
-data: dictionary, list, string, assign empty value to it---》http response body
-status:http response status code from rest_framework import status
-headers: response headers
res=HttpResponse() res=render() res=redirect() res=JsonResponse() One of the four-piece set
res['name']='lin' #Put it in the response header
return res
-Response encoding format---》Generally does not move
# 3 Two view base classes
-APIView---》Write 5 interfaces
-GenericAPIView inherits from APIView---》Use it when dealing with the database and serializing in the future.
### Important attributes###
-queryset: Put all the data queried from a certain table in the future
-serializer_class: the class to be serialized
### Important methods###
-get_queryset: all data to be serialized, qs object
-get_serializer: serialization class
-get_object: modify, query, delete a single item
# 4 5 view extension classes
RetrieveModelMixin,
CreateModelMixin,
DestroyModelMixin,
ListModelMixin,
UpdateModelMixin
Two 9 view subclasses
from rest_framework.generics import ListAPIView, CreateAPIView, ListCreateAPIView
from rest_framework.generics import RetrieveAPIView, DestroyAPIView, UpdateAPIView
from rest_framework.generics import RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView
# If you want to write one, some, or all of the five interfaces in the future, you only need to choose to inherit from different classes. You only need to configure two class attributes in the class.
queryset = Publish.objects.all()
serializer_class = PublishSerializer
1 View class
#1 I want to write publish: query all, query a single item, modify an item, add an item, delete an item interface
class PublishView(ListCreateAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
class PublishDetailView(RetrieveUpdateDestroyAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
#2 Want to write publish: Query a single item, add one, the interface ---> use 9 view subclasses to write
class PublishView(CreateAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
class PublishDetailView(RetrieveAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
#3 Want to write publish: Query a single item, add one, the interface ---> use 5 view extension classes + GenericAPIView
class PublishView(GenericAPIView,CreateModelMixin):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
def post(self,request,*args,**kwargs):
return self.create(request,*args,**kwargs)
class PublishDetailView(GenericAPIView,RetrieveModelMixin):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
def get(self,request,*args,**kwargs):
return self.retrieve(request,*args,**kwargs)
2 Routing
path('publish/', PublishView.as_view()),
path('publish/<int:pk>', PublishView.as_view()),
Three views
1 ModelViewSet
# 1 As long as the view class inherits it and changes the routing method, 5 interfaces will be available.
from rest_framework.viewsets import ModelViewSet
class PublishView(ModelViewSet):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
path('publish/', PublishView.as_view({<!-- -->'get':'list','post':'create'})),
path('publish/<int:pk>', PublishView.as_view({<!-- -->'get':'retrieve','put':'update','delete':'destroy'})) ,
1.1 ModelViewSet source code analysis
# Query all interfaces
-get--list----》Get all data, serialize--return
# Add a new item
-post---create---》The new code we wrote before is the same
# Why does get become a list?
# Why post becomes create
2 ViewSetMixin
# Never seen
# ViewSetMixin has been decided, and the way to write routes will change in the future.
-path('publish/', PublishView.as_view({<!-- -->'get':'list','post':'create'}))
-path('publish/', PublishView.as_view({<!-- -->'get':'lqz'}))
# Source code analysis
-class GenericViewSet(ViewSetMixin, generics.GenericAPIView): ViewSetMixin must be placed in front--" Ensure that the executed as_view is ViewSetMixin
-The request comes and the route is matched successfully---》Execute view(request) in as_view of ViewSetMixin
def view(request, *args, **kwargs):
self = cls(**initkwargs) # Get the object from class instantiation--"Whose object is self?" PublishView
self.action_map = actions # {'get':'list','post':'create'}
# method:get
# action: list
for method, action in actions.items():
# list method
handler = getattr(self, action) #Reflection list in PublishView object, got it
# Reflection setting value
#setattr (object of PublishView view class, get, list methods)
# There will be a get method in the object of the PublishView view class, which is list
setattr(self, method, handler)
return self.dispatch(request, *args, **kwargs)
# Summarize:
-Configure like this in routing: PublishView.as_view({<!-- -->'get':'list','post':'create'})
-After the get request comes in, what is essentially executed is the list method in the view class.
2.1 In the future, the method names in the view class can be named arbitrarily, as long as the routing is properly mapped
# The inherited class is: as long as you inherit ViewSetMixin, you can name the methods in the view class arbitrarily, and the routing writing method can be changed.
3 ReadOnlyModelViewSet
# The interface to be written in the future only wants to get a single item and get all, inherit it.
4 Summary of classes in the view layer
# 1 Two view base classes
-APIView and GenericAPIView
-APIView execution process: wraps new, handles csrfrequeset, performs three major authentications, and handles global exceptions
-GenericAPIView: If you want to serialize and deal with the database, just inherit it directly.
-queryset
-serializer_class
-get_object
-get_queryset
-get_serializer
# 2 5 view extension classes (not view classes), which require GenericAPIView to be used
-Quickly use 5 interfaces
- Certain interfaces: Query a single item, add one, interface ---> use 5 view extension classes + GenericAPIView
class PublishView(GenericAPIView,CreateModelMixin)
queryset=Publish.objects.all()
serializer_class=Serializer class
def post(self,request)
return self.create(request)
class PublishDetailView(GenericAPIView,RetrieveModelMixin)
queryset=Publish.objects.all()
serializer_class=Serializer class
def get(self,request)
return self.retrieve(request)
# 3 9 view subclasses (a combination of inheriting GenericAPIView + 5 view extension classes)
ListAPIView, CreateAPIView
ListCreateAPIView
RetrieveAPIView, DestroyAPIView, UpdateAPIView
RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView
#4 Viewset
-ModelViewSet:
-ViewSetMixin + GenericAPIView + 5 view extension classes
-GenericViewSet + 5 view extension classes
-ViewSetMixin source code: Routing mapping configuration, the methods in the view class can be named casually in the future
-Viewset: ViewSetMixin + APIView---》No need for serialization, the routing writing method has changed
-GenericViewSet: ViewSetMixin + GenericAPIView--》Needs serialization, needs to use database, routing writing method changes
-ReadOnlyModelViewSet: list and retrieve
Four drf reasons
#Previous routing writing method:
path('books/', BookView.as_view())
# Once you inherit ViewSetMixin in the future, it will become path('publish/', PublishView.as_view({'get': 'list', 'post': 'create'}))
# It may be a bit troublesome to write and map like this, so drf helps us encapsulate two routing classes ---" can help us quickly generate the mapping relationship we wrote before
###### Must inherit ViewSetMixin + APIView and its subclasses to automatically generate SimpleRouter DefaultRouter
## Automatically generate routes: automatic mapping is as follows:
{<!-- -->'get': 'list', 'post': 'create'}
{<!-- -->'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}
## Others-->There are other methods in the view class. If we want to map, we need to use a decorator.
How to use
# Major premise: You must inherit ViewSetMixin + APIView and its subclasses to automatically generate
####Steps for usage
# urls.py
#### 1 Import routing class
from rest_framework.routers import SimpleRouter, DefaultRouter
#### 2 Class instantiation to get the object
router = SimpleRouter()
#### 3 Automatically generate routes, call a certain method of the object, complete the corresponding relationship with the view class, and map the route
router.register('publish', PublishView, 'publish')
# router.register('books', BookView, 'books') # You can register more later
router.register('user',UserView,'user')
##### 4 Add the automatically generated route to the total route
urlpatterns = urlpatterns + router.urls # Add the two lists directly
### The fourth step can be written like this
path('api/v1/', include(router.urls)), # http://127.0.0.1:8008/api/v1/user/register/--->post
1 SimpleRouter, DefaultRouter
The difference between SimpleRouter and DefaultRouter
The path generated by -DefaultRouter has one more root path api-root
-DefaultRouter will come with a default API root view and return a hyperlink response data containing all list views.
Use it from now on: SimpleRouter will do
2 action decorator
# Function: Map paths for methods in view classes
-These methods need to exclude 5: create, list, destroy, update, retrieve
# Usage
@action(methods=['POST'],detail=False)
def register(self, request):
return Response('register')
# Automatic generated:
http://127.0.0.1:8008/user/register/---->post--->will execute register
# action parameters
-methods request method, you can write multiple
-detail: Whether there is an ID number in the path
http://127.0.0.1:8008/user/register/ # detail=False
http://127.0.0.1:8008/user/4/register/ # detail=True
************************* Code display************************ **********
-1.Routing
from django.contrib import admin
from django.urls import path
from app01.views import UserView
# 1. Import routing class
from rest_framework.routers import SimpleRouter, DefaultRouter
# 2. Class instantiation to obtain the object
router = SimpleRouter()
# 3. Automatically generate routes, call a certain method of the object, complete the corresponding relationship with the view class, and map the route
router.register('user', UserView, 'user')
urlpatterns = [
path('admin/', admin.site.urls),
# Access login/path post request will execute the register method in UserView
path('register/', UserView.as_view({<!-- -->'post': 'register'})),
]
urlpatterns + = router.urls
-2.View function
from rest_framework.decorators import action
class UserView(GenericViewSet):
# http://127.0.0.1:8000/user/register/ ----> post -----> is to execute register
# url_path is the name after the path. If not written, the method name will be used as the path.
# @action(methods=['POST'], detail=False, url_path='reg')
# methods request method
# detail whether to include id
# @action(methods=['POST'], detail=False)
@action(methods=['POST'], detail=True)
# def register(self, request):
# http://127.0.0.1:8000/user/2/register/
def register(self, request, pk):
print(pk)
# self.get_queryset()
return Response('register')
3 In the future, inheriting ModelViewSet may also override many methods
#### Rewrite list
class PublishView(ModelViewSet):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
def list(self, request, *args, **kwargs): # We may rewrite the list in the future and make our own customizations
res=super().list(request, *args, **kwargs)
return Response({<!-- -->'code':100,'msg':'success','result':res.data})
### Override get_serializer_class
def get_serializer_class(self): # It is a method in the GenericAPIView class. Whatever is returned, the serialization class will be used to continue the operation in the future.
print(self.action)
if self.request.method=='POST':
return WritePublishSerializer
else:
return self.serializer_class
### Override perform_create
def perform_create(self, serializer):
serializer.save()
### Use PublishSerializer for serialization and WritePublishSerializer for deserialization.
4 Action parameters in the object of the view class
print(self.action)
# There is an action attribute in the object of the view class---》It is the string of the method name executed by the current request.
# Through action, you can limit which serialization class is used by a method in the view class.
Usage of importlib
`importlib` is a module in the Python standard library. It provides a way to dynamically import modules and obtain module information.
Allows you to load, import, and use Python modules at runtime. This is useful for writing scalable, flexible code and plugin systems.
Here are some common usage examples of the `importlib` module:
1. **Dynamic import module**:
import importlib
# Dynamically import modules
module_name = "my_module"
my_module = importlib.import_module(module_name)
# Use dynamically imported modules
result = my_module.my_function()
2. **Import objects from modules**:
import importlib
# Dynamically import modules
module_name = "my_module"
my_module = importlib.import_module(module_name)
#Import objects from modules
my_function = getattr(my_module, "my_function")
# Use imported objects
result = my_function()
3. **Reload module**:
import importlib
# Dynamically import modules
module_name = "my_module"
my_module = importlib.import_module(module_name)
# Reload module
my_module = importlib.reload(my_module)
4. **Get the file path of the module**:
import importlib
# Dynamically import modules
module_name = "my_module"
my_module = importlib.import_module(module_name)
# Get the file path of the module
module_path = my_module.__file__
These examples demonstrate how to use `importlib` to dynamically import modules, import objects from modules,
Reload the module and get the module's file path.
These features can be used for building plug-in systems, modular applications, and dynamically loaded modules.
5. GenericViewSet related flow chart
1.GenericViewSet inheritance flow chart
2.minix and GenericViewSet flow chart
3.Flow chart of the relationship between minix and GenericViewSet
6. rest_framework map