03_Tutorial 3: Class-based Views 基于类的视图(CBV)
1、CBV
0、文档
https://q1mi.github.io/Django-REST-framework-documentation/tutorial/3-class-based-views_zh/
https://www.django-rest-framework.org/tutorial/3-class-based-views/
1、方式1:APIView
# 方式1:APIView 使用基于类的视图重写我们的API
# 使用基于类视图的最大优势之一是它可以轻松地创建可复用的行为
from rest_framework.views import APIView from django.http import Http404 class SnippetList31(APIView): """ 列出所有的snippets或者创建一个新的snippet。 """ def get(self, request, format=None): snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) # 序列化多个,many=True return Response(serializer.data) def post(self, request, format=None): serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class SnippetDetail31(APIView): """ 检索,更新或删除一个snippet示例。 """ def get_object(self, pk): # 封装 """queryset实例对象""" try: return Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: raise Http404 def get(self, request, pk ,format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet) return Response(serializer.data, status=status.HTTP_200_OK) def put(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): snippet = self.get_object(pk) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
2、方式2:使用混合(mixins)
1、mixin类 和 GenericAPIView类
mixin类提供.list()和.create()操作
GenericAPIView类来提供核心功能, 继承APIView
2、get_queryset()`/`get_serializer_class()
queryset = None
serializer_class = None
# 方式2:使用混合(mixins) from rest_framework import mixins from rest_framework import generics class SnippetList32(mixins.ListModelMixin, # mixin类提供.list()和.create()操作 mixins.CreateModelMixin, generics.GenericAPIView): # GenericAPIView类来提供核心功能, 继承APIView # GenericAPIView中,重写view视图需要 # 用`get_queryset()`/`get_serializer_class()`替代queryset # 一次获取queryset,结果会被缓存,可以多次使用 # queryset = None # serializer_class = None queryset = Snippet.objects.all() # queryset实例对象 serializer_class = SnippetSerializer # 序列化器 def get(self, request, *args, **kwargs): # get绑定到list() return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): # post绑定到create() return self.create(request, *args, **kwargs) class SnippetDetail32(mixins.RetrieveModelMixin, # Retrieve 检索某个 mixins.UpdateModelMixin, # update 更新某个 mixins.DestroyModelMixin, # destroy 删除某个 generics.GenericAPIView): queryset = Snippet.objects.all() serializer_class = SnippetSerializer 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 delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
3、方式3:使用通用的基于类的视图:generics
1、get、post
class SnippetList(generics.ListCreateAPIView)
2、单个的增删改查
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView)
from rest_framework import generics class SnippetList(generics.ListCreateAPIView): # list create queryset = Snippet.objects.all() serializer_class = SnippetSerializer class SnippetDetail(generics.RetrieveUpdateDestroyAPIView): # 检索,更新,删除 queryset = Snippet.objects.all() serializer_class = SnippetSerializer