06 类视图
APIView
基于类的视图编写API视图,允许我们重用常用的功能。
基于类视图重写API
from snippets.models import Snippetfrom snippets.serializers import SnippetSerializerfrom django.http import Http404from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import statusclass SnippetList(APIView):"""列出所有的snippets或者创建一个新的snippet。"""def get(self, request, format=None):snippets = Snippet.objects.all()serializer = SnippetSerializer(snippets, 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 SnippetDetail(APIView):"""检索,更新或删除一个snippet示例。"""def get_object(self, pk):try:return Snippet.objects.get(pk=pk)except Snippet.DoesNotExist:raise Http404def get(self, request, pk, format=None):snippet = self.get_object(pk)serializer = SnippetSerializer(snippet)return Response(serializer.data)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)
ViewSets
REST框架包含一个用于处理的抽象概念 ViewSets,它允许开发人员专注于对API的状态和交互进行建模,并根据通过约定自动处理URL构造。
viewsets = (view1, view2, view3, viewN...)
DRF允许您将一组相关的视图view逻辑的组合到一个类中,称为一个ViewSet
ViewSet类与View类几乎相同- 它不提供任何方法处理程序,如(get/post/),而是提供诸如(list/create/read/update)
- 一个
ViewSet类只在最后时刻绑定到一组方法处理程序,当它被实例为一组视图时,通常通过使用一个Router类来处理复杂的URL conf
使用ViewSet重构
将UserList和UserDetail观点重构成一个单一的UserViewSet。我们可以删除这两个视图,并用一个类来替换它们。
from rest_framework import viewsetsclass UserViewSet(viewsets.ReadOnlyModelViewSet):"""此视图集自动提供‘list’和‘detail’操作"""queryset = User.objects.all()serializer_class = UserSerializer
ReadOnlyModelViewSet自动提供默认的“只读”操作。
将SnippetList,SnippetDetail和SnippetHighlight视图类更换为一个SnippetViewSet
from rest_framework.decorators import actionfrom rest_framework.response import Responseclass SnippetViewSet(viewsets.ModelViewSet):"""此视图集自动提供“list”、“create”、“retrieve”、“update”和“destroy”操作"""queryset = Snippet.objects.all()serializer_class = SnippetSerializerpermission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)@action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])def highlight(self, request, *args, **kwargs):snippet = self.get_object()return Response(snippet.highlighted)def permform_create(self, serializer):serializer.save(owner=self.request.user)
继承自ModelViewSet类,提供完整的读写操作。
@action装饰自定义操作highlight。用来添加任何不符合标准create/update/delete的自定义endpoints@action默认处理GET请求,如果要处理POST请求,可以使用method参数来指定
view与viewsets之间权衡
viewsets是一个非常有用的抽象
- 有助于确保URL在API中保持一致,最大限度地减少需要编写的代码量
- 使用viewsets时,不如view更明确。
