06 类视图
APIView
基于类的视图编写API视图,允许我们重用常用的功能。
基于类视图重写API
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class 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 Http404
def 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 viewsets
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
此视图集自动提供‘list’和‘detail’操作
"""
queryset = User.objects.all()
serializer_class = UserSerializer
ReadOnlyModelViewSet
自动提供默认的“只读”操作。
将SnippetList,SnippetDetail和SnippetHighlight
视图类更换为一个SnippetViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
class SnippetViewSet(viewsets.ModelViewSet):
"""
此视图集自动提供“list”、“create”、“retrieve”、“update”和“destroy”操作
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_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更明确。