Django基于类的视图(CBV)
Django View
class View:
@classonlymethod
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
# 实例化,cls为子类
self = cls(**initkwargs)
return self.dispatch(request, *args, **kwargs)
# 返回view,本质和FBV类似
return view
def dispatch(self, request, *args, **kwargs):
# get/post/put/patch/delete...
handler = getattr(self, request.method.lower()
# 相当于调用get()/post()...
return handler(request, *args, **kwargs)
DRF APIView
class APIView(View):
@classmethod
def as_view(cls, **initkwargs):
# 调用Django的as_view方法
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# 将视图函数标记为不受CSRF视图保护
return csrf_exempt(view)
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs)
# 此时的request是drf的request
self.request = request
# 初始化认证、权限、限流三件套
self.initial(request, *args, **kwargs)
# get/post/put/patch/delete...
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
# 相当于调用get()/post()...
response = handler(request, *args, **kwargs)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
DRF GenericAPIView
class GenericAPIView(views.APIView):
queryset = None
serializer_class = None
lookup_field = 'pk'
lookup_url_kwarg = None
def get_queryset(self):
"""
获取queryset
"""
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
return queryset
def get_object(self):
"""
获取单个object
"""
queryset = self.filter_queryset(self.get_queryset())
# Perform the lookup filtering.
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
# 过滤条件,key:默认pk,value:对应的主键值
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
return obj
def get_serializer(self, *args, **kwargs):
"""
获取序列化器实例
"""
serializer_class = self.get_serializer_class()
# 实例化序列化器,instance,data,many
return serializer_class(*args, **kwargs)
def get_serializer_class(self):
"""
获取序列化器类
"""
return self.serializer_class
DRF的各个Mixin, 提取CURD操作的通用逻辑到Mixin
CreateModelMixin 创建
class CreateModelMixin:
"""
Create a model instance.
"""
def create(self, request, *args, **kwargs):
# 获取序列化器实例
serializer = self.get_serializer(data=request.data)
# 校验
serializer.is_valid(raise_exception=True)
# 创建
self.perform_create(serializer)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
ListModelMixin 列表
class ListModelMixin:
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
RetrieveModelMixin 详情
class RetrieveModelMixin:
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
# 和GenericAPIView配合使用,调用GenericAPIView中的方法
instance = self.get_object()
# 调用GenericAPIView中的方法
serializer = self.get_serializer(instance)
return Response(serializer.data)
UpdateModelMixin 更新
class UpdateModelMixin:
"""
Update a model instance.
"""
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
return Response(serializer.data)
DestroyModelMixin 删除
class DestroyModelMixin:
"""
Destroy a model instance.
"""
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance):
instance.delete()
GenericAPIView和各个Mixin再封装
CreateAPIView 创建
class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for creating a model instance.
"""
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
ListAPIView 列表
class ListAPIView(mixins.ListModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
RetrieveAPIView 详情
class RetrieveAPIView(mixins.RetrieveModelMixin,
GenericAPIView):
"""
Concrete view for retrieving a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
DestroyAPIView 删除
class DestroyAPIView(mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for deleting a model instance.
"""
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
UpdateAPIView 更新
class UpdateAPIView(mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for updating a model instance.
"""
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
ListCreateAPIView 列表和创建
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset or creating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
RetrieveUpdateAPIView 详细和更新
class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
RetrieveDestroyAPIView 详情和删除
class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving or deleting a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
RetrieveUpdateDestroyAPIView 详情、更新和删除
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating or deleting a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
ViewSetMixin
class ViewSetMixin:
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
def view(request, *args, **kwargs):
self = cls(**initkwargs)
self.action_map = actions
# 最关键的循环地方,类似 self.get = get_object,覆盖原有默认的get/post/delete...
for method, action in actions.items():
handler = getattr(self, action)
setattr(self, method, handler)
return self.dispatch(request, *args, **kwargs)
return csrf_exempt(view)
ViewSet 在GenericAPIView基础上增加映射机制
class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass
GenericViewSet 在GenericAPIView基础上增加映射机制
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
ModelViewSet
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
注册路由
from rest_framework.routers import DefaultRouter
from .views import BookViewSet
router = DefaultRouter()
router.register(r'books', BookViewSet, basename='book') # 关键注册方法
urlpatterns = router.urls
自动生成的路由

浙公网安备 33010602011771号