第三章 基于类的视图
写在前面:
本文翻译于django rest framework官方文档,由于网上大多数django rest framework中文翻译文档都有较为多的删减行为,笔者在学习的时候就觉得不是太方便,故笔者将官方文档较为完善的为大家翻译下,仅供大家学习参考。由于笔者文笔有限,若有写得不当之处,敬请各位同仁指出;若涉及到侵权,请联系笔者,笔者将立即删除。
我们还可以使用基于类的视图而不是基于函数的视图来编写我们的API视图。 我们将看到这是一个强大的模式,允许我们重用通用功能,并帮助我们保持我们的代码DRY
1. 使用基于类的视图来重写我们的API
首先我们从重写我们的根视图来使用基于类的视图,所有的这些都只要重构一点点我们的views.py
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):
"""
列出所有的实例或者创建一个新的实例
"""
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)
对于某个实例,我们重写SnippetDetail
class SnippetDetail(APIView):
"""
检索,更新或者删除实例
"""
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)
现在,我们的视图仍然和基于函数的视图比较类似,现在我们还要重构我们的urls.py
文件
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = [
url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
好的,我们的工作完成了,当你这个时候打开服务器,你会发现我们的项目会和原来一模一样的运行。
2. 使用mixins
使用基于类的视图的一大亮点是它允许我们轻松地组成可重用的行为。
到目前为止,我们使用的创建/检索/更新/删除操作对于我们创建的任何模型支持的API视图都非常相似。 这些常见的行为在REST Framework
的mixin
类中实现。
让我们来看看如何使用mixin
类来构造视图。 这里是我们的views.py
模块。
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import mixins
from rest_framework import generics
class SnippetList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
我们现在花一点时间来解释下现在是个什么状况。我们使用了GenericAPIView
来构建视图,并添加了ListModelMixin
和CreateModelMixin
mixins
这个基类提供了这些核心功能,并且mixins
类提供了.list()
和.create()
操作,然后我们将这些操作和get()
方法和post()
绑定上。
class SnippetDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
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)
一样的,我们又一次用到了GenericAPIView
类来提供核心功能,然后我们添加mixins
类提供的.retrive()
,.update()
,.destroy()
操作。
3. 使用通用的基于类的视图
使用mixins
类我们使用了更少的代码来重写了我们的视图,REST Framework
已经提供了一组已经混合了的通用视图,我们可以使用它来简化我们的views.py
模块。
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
是不是感觉很不错,我们只使用了很少很少的代码,而且我们的代码看起来很干净,这很Django
接下来,我们将来讨论教程的第4章,我们将介绍如何处理我们API的身份验证和权限。
谢谢各位阅读,并欢迎各位留下宝贵意见