1. GenericAPIView class source code
class GenericAPIView(views.APIView):
"""
Base class for all other generic views.
"""
# You'll need to either set these attributes,
# or override `get_queryset()`/`get_serializer_class()`.
# If you are overriding a view method, it is important that you call
# `get_queryset()` instead of accessing the `queryset` property directly,
# as `queryset` will get evaluated only once, and those results are cached
# for all subsequent requests.
queryset = None
serializer_class = None
# If you want to use object lookups other than pk, set 'lookup_field'.
# For more complex lookup requirements override `get_object()`.
lookup_field = 'pk'
lookup_url_kwarg = None
# The filter backend classes to use for queryset filtering
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
# The style to use for queryset pagination.
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get_queryset(self):
"""
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using `self.queryset`.
This method should always be used rather than accessing `self.queryset`
directly, as `self.queryset` gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different
querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
"""
assert self.queryset is not None, (
"'%s' should either include a `queryset` attribute, "
"or override the `get_queryset()` method."
% self.__class__.__name__
)
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset
def get_object(self):
"""
Returns the object the view is displaying.
You may want to override this if you need to provide non-standard
queryset lookups. Eg if objects are referenced using multiple
keyword arguments in the url conf.
"""
queryset = self.filter_queryset(self.get_queryset())
# Perform the lookup filtering.
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
assert lookup_url_kwarg in self.kwargs, (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwarg)
)
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
# May raise a permission denied
self.check_object_permissions(self.request, obj)
return obj
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs.setdefault('context', self.get_serializer_context())
return serializer_class(*args, **kwargs)
def get_serializer_class(self):
"""
Return the class to use for the serializer.
Defaults to using `self.serializer_class`.
You may want to override this if you need to provide different
serializations depending on the incoming request.
(Eg. admins get full serialization, others get basic serialization)
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
return self.serializer_class
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
def filter_queryset(self, queryset):
"""
Given a queryset, filter it with whichever filter backend is in use.
You are unlikely to want to override this method, although you may need
to call it either from a list view, or from a custom `get_object`
method if you want to apply the configured filtering backend to the
default queryset.
"""
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
@property
def paginator(self):
"""
The paginator instance associated with the view, or `None`.
"""
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class()
return self._paginator
def paginate_queryset(self, queryset):
"""
Return a single page of results, or `None` if pagination is disabled.
"""
if self.paginator is None:
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
def get_paginated_response(self, data):
"""
Return a paginated style `Response` object for the given output data.
"""
assert self.paginator is not None
return self.paginator.get_paginated_response(data)
2. Introduction to GenericAPIView
GenericAPIView is a basic view class in Django REST Framework (DRF), which provides developers with some general functions and methods for quickly building API views.
The GenericAPIView class is created by combining the APIView and GenericAPIViewMixin classes. It inherits the APIView class and mixes in the methods and properties of the GenericAPIViewMixin class.
2.1 Key features and common methods of the GenericAPIView class:
2.1.1 Provide common HTTP method processing functions:
The GenericAPIView class provides common HTTP method processing functions, such as
- get(): handle HTTP GET requests;
- post(): handle HTTP POST requests;
- put(): handle HTTP PUT requests;
- patch(): handle HTTP PATCH requests;
- delete(): handle HTTP DELETE requests;
- head(): handle HTTP HEAD requests;
- options(): Handle HTTP OPTIONS requests
You can implement processing logic for different HTTP methods by overriding these methods.
Notice:
Inherit the GenericAPIView class, you need to manually rewrite the HTTP method processing function
1. The GenericAPIView class provides common HTTP method processing functions, which are actually implemented by the APIView class
The GenericAPIView class inherits the APIView class and extends its functionality by mixing in some Mixin classes. It does not directly implement all HTTP method processing functions, but borrows the corresponding methods already implemented in the APIView class. These methods include:
- get(): handle HTTP GET requests;
- post(): handle HTTP POST requests;
- put(): handle HTTP PUT requests;
- patch(): handle HTTP PATCH requests;
- delete(): handle HTTP DELETE requests;
- head(): handle HTTP HEAD requests;
- options(): Handles HTTP OPTIONS requests.
The APIView class is the most basic view class in DRF. It defines the default behaviors corresponding to each method, but these default behaviors usually need to be customized according to specific situations. Therefore, the GenericAPIView class, as a subclass of the APIView class, provides more flexible and customizable view functions.
By inheriting the GenericAPIView class and rewriting related methods according to specific requirements, developers can easily implement their own view logic and business processing. In actual use, we generally combine the Mixin classes of the GenericAPIView class (such as ListAPIView, RetrieveAPIView, etc.) to further simplify the development process and achieve more specific functions.
2. Support a variety of commonly used data operations:
The GenericAPIView class encapsulates common data operations, including operations such as obtaining query sets, filtering, sorting, and paging. It provides some attributes and methods, such as queryset, filter_queryset(), paginate_queryset(), etc., through which the logic of data manipulation can be easily realized.
3. Built-in common Mixin class methods:
The GenericAPIView class has some commonly used Mixin class methods built in.
The following are several commonly used Mixin class methods built into the GenericAPIView class:
- ListAPIView: This Mixin class implements the logic of processing GET requests to return list data. It provides default list data query and serialization logic, you only need to specify the query set and serializer in the subclass.
- CreateAPIView: This Mixin class implements the logic for handling POST requests to create resources. It provides default request data deserialization and storage logic, you only need to specify the serializer in the subclass.
- RetrieveAPIView: This Mixin class implements the logic for processing GET requests to retrieve a single resource. It provides default resource query and serialization logic, you only need to specify the query set and serializer in the subclass.
- UpdateAPIView: This Mixin class implements the logic for handling PUT/PATCH requests to update resources. It provides the default request data deserialization, resource query and storage logic, you only need to specify the query set and serializer in the subclass.
- DestroyAPIView: This Mixin class implements the logic for handling DELETE requests to delete resources. It provides default resource query and deletion logic, you only need to specify the query set in the subclass.
These mixin methods can be used with the GenericAPIView class to build view classes that meet specific needs. You can choose and combine these Mixin class methods according to your needs to implement common REST functions in view classes.
For example, if you want to create a view class that handles GET requests to return list data, you can derive a new subclass from GenericAPIView and ListAPIView, and specify querysets and serializers in the subclass. The view class will then automatically provide query and serialization functionality for the list data.
from rest_framework.generics import GenericAPIView, ListAPIView
from myapp.models import MyModel
from myapp.serializers import MyModelSerializer
class MyListView(GenericAPIView, ListAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
In the above example, we defined a view class named MyListView which inherits from GenericAPIView and ListAPIView. We specified the query set (queryset) and the serializer (serializer_class), so that the view class has the function of processing the list data returned by the GET request.
By using these built-in Mixin class methods, you can more easily build view classes that meet your needs and reduce the writing of repeated codes.
4. Support the use of serializer classes:
The GenericAPIView class provides a serializer_class attribute for specifying the serializer class to use. The instantiated serializer object can be obtained through the get_serializer() method, and used in the view to perform data serialization and deserialization operations.
5. Simplified API view development:
The development of API views can be greatly simplified with the help of the GenericAPIView class and related Mixin classes. They provide many common methods and attributes, reducing the workload of repetitive code writing and improving development efficiency.
All in all, the GenericAPIView class is a very useful basic view class in the DRF framework. By inheriting and combining related Mixin classes, it provides many common functions and methods, which simplifies the development process of API views. Developers can quickly build an API view that conforms to the RESTful design style according to their own needs, combined with the characteristics of the GenericAPIView class.