GenericAPIView
GenericAPIView inherits from APIView and adds general support methods that may be used for list view and detail view. Usually, it can be used with one or more Mixin extension classes.
attribute
Basic settings:
The following properties control the behavior of the base view.
List view: get multiple pieces of data (or all data), for example: get all books
Detail view: obtain single data, such as the price, author, publishing house, etc. of journey to the West.
List view and detail view are common
- queryset applies to the query set of objects returned from this view. Typically, you must set this property or override it_ queryset() method. If you want to override the view method, be sure to call get_queryset() instead of accessing this property directly.
- serializer_class should be used to validate and deserialize the input and serialize the output. Typically, you must set this property or override it_ serializer_class() method.
Details view usage
- lookup_field should be used to perform object lookup for a single model instance. The default is' pk '
- lookup_ url_ The URL keyword parameter that kwarg should use for object lookup. The URL conf should contain a keyword parameter corresponding to this value. If not set, lookup is used by default_ field.
paging
The following properties are used to control paging when used with list views.
- pagination_class is the paging class that should be used when paging list results. The default is and DEFAULT_PAGINATION_CLASS sets the same value, that is, 'rest'_ framework. pagination. PageNumberPagination’. Setting pagination_class=None will disable paging for this view.
filter
- filter_backends a list of filter backend classes that are applied to filter the query set. Default and DEFAULT_FILTER_BACKENDS settings are the same.
method
List view and detail view are common
get_queryset(self) returns the query set used by the view. It is the basis for obtaining data from list view and detail view. The queryset property is returned by default and can be rewritten, for example:
def get_queryset(self): return BookInfo.objects.all()
get_serializer_class(self) returns the serializer class. Serializer is returned by default_ Class, which can be overridden, for example:
def get_serializer_class(self): return BookInfoModelSerializer
get_serializer(self, _args, *_kwargs) returns the serializer object, which is used by other views or extension classes. If we want to get the serializer object in the view, we can call this method directly.
Details view usage
get_object(self) returns the model class data object required by the detail view. Lookup is used by default_ Field parameter to filter queryset. The model class object that can call this method to obtain detailed information in the view.
If the model class object accessed in detail does not exist, 404 will be returned.
Experience: GenericAPIView looks very beautiful and can be combined with various mixin s, but it is not very useful in fact. This is because the development speed is improved at most, but if the product modifies the requirements, the corresponding serializer must be changed. Then, some interfaces need A serializer for data verification, and some need B serializer. It is very inconvenient to change GenericAPIView at this time.
Suggestion: use FVB mode for development, which is easy to modify, or there is only one method in each CVB, but it is not as good as using FVB directly.
Here are some examples. Some of these examples use pagers. This does not affect our understanding. If you don't know the of the DRF pager, you can see it here
Lists and new views
In the list view, multiple data are returned according to the page size at a time. As shown in the figure below, when we use Baidu search, Baidu will show us the data in the form of pagination.

Our list view code is as follows:
class PageNum(PageNumberPagination): """Pager class""" page_size = 10 # By default, the number of entries returned per page page_query_param = 'pagenum' #Set the key of page in the url. The default is page page_size_query_param = 'pagesize' # Set page in url_ The size key, which defaults to page_size max_page_size = 50 # Maximum number of entries returned per page class BookListView(GenericAPIView): """List view""" queryset = BookInfo.objects.all().order_by('id') serializer_class = BookInfoSerializer pagination_class = PageNum def get(self, request): """GET Request get list""" data = self.get_queryset() # Get query result set page = self.paginate_queryset(data) #Pagination of query result set serializer = self.get_serializer(page, many=True) # serialize return Response(serializer.data) # Return value def post(self, request): """post Request new""" data = request.data serializer = self.get_serializer(data=data) if serializer.is_valid(raise_exception=True): serializer.save() return Response(serializer.data, status=201) else: # Return error message return Response({'msg': 'Save failed'}, status=400)
Use the GET method to request. The effect is as follows:

After adding successfully, the returned response is as follows:

The reason why the list method and the new method are placed in one class is that "the URLs used by the two methods are the same, while the URLs used to query a piece of data details, modify an existing piece of data, and delete a piece of data are the same."
Delete modify query view
The view will include three functions: deleting a piece of data, modifying a piece of data and obtaining the details of a piece of data. The corresponding HTTP request methods are DELETE, PUT and GET respectively. They use the same URL.
class BookView(GenericAPIView): """Delete modify query view""" queryset = BookInfo.objects.all() serializer_class = BookInfoSerializer lookup_field = 'pk' lookup_url_kwarg = 'pk' def get(self, request, pk): """according to id Query book details""" obj = self.get_object() serializers = self.get_serializer(obj) return Response(serializers.data) def delete(self, request, pk): """according to id Delete books""" obj = self.get_object() obj.delete() return Response(status=204) def put(self, request, pk): """according to id Modify the information of a Book""" obj = self.get_object() data = request.data serializers = self.get_serializer(obj, data) if serializers.is_valid(raise_exception=True): serializers.save() # PUT update. If data is returned, the recommended status code is 200; If no data is returned, the status code can be 204 or 205 according to the situation return Response(serializers.data, status=200) else: return Response(status=400)
Our URL design is as follows:
path('book', BookListView.as_view()), path('book/<int:pk>', BookView.as_view()),
use http://127.0.0.1:8848/book/3 Make a request, and the returned response is as follows:

This basically reflects the design idea of RESTFul. Only nouns are involved in the URL, the interface is unified, and the HTTP request method is used to distinguish actions. Different HTTP methods represent different operations on resources.