第三章 基于類(lèi)的視圖
寫(xiě)在前面:
本文翻譯于django rest framework官方文檔,由于網(wǎng)上大多數(shù)django rest framework中文翻譯文檔都有較為多的刪減行為午笛,筆者在學(xué)習(xí)的時(shí)候就覺(jué)得不是太方便鱼辙,故筆者將官方文檔較為完善的為大家翻譯下,僅供大家學(xué)習(xí)參考矗烛。由于筆者文筆有限辅柴,若有寫(xiě)得不當(dāng)之處,敬請(qǐng)各位同仁指出瞭吃;若涉及到侵權(quán)碌嘀,請(qǐng)聯(lián)系筆者,筆者將立即刪除歪架。
我們還可以使用基于類(lèi)的視圖而不是基于函數(shù)的視圖來(lái)編寫(xiě)我們的API視圖股冗。 我們將看到這是一個(gè)強(qiáng)大的模式,允許我們重用通用功能和蚪,并幫助我們保持我們的代碼DRY
1. 使用基于類(lèi)的視圖來(lái)重寫(xiě)我們的API
首先我們從重寫(xiě)我們的根視圖來(lái)使用基于類(lèi)的視圖止状,所有的這些都只要重構(gòu)一點(diǎn)點(diǎn)我們的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):
"""
列出所有的實(shí)例或者創(chuàng)建一個(gè)新的實(shí)例
"""
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)
對(duì)于某個(gè)實(shí)例烹棉,我們重寫(xiě)SnippetDetail
class SnippetDetail(APIView):
"""
檢索,更新或者刪除實(shí)例
"""
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)
現(xiàn)在怯疤,我們的視圖仍然和基于函數(shù)的視圖比較類(lèi)似浆洗,現(xiàn)在我們還要重構(gòu)我們的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<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
好的,我們的工作完成了集峦,當(dāng)你這個(gè)時(shí)候打開(kāi)服務(wù)器伏社,你會(huì)發(fā)現(xiàn)我們的項(xiàng)目會(huì)和原來(lái)一模一樣的運(yùn)行。
2. 使用mixins
使用基于類(lèi)的視圖的一大亮點(diǎn)是它允許我們輕松地組成可重用的行為塔淤。
到目前為止洛口,我們使用的創(chuàng)建/檢索/更新/刪除操作對(duì)于我們創(chuàng)建的任何模型支持的API視圖都非常相似。 這些常見(jiàn)的行為在REST Framework
的mixin
類(lèi)中實(shí)現(xiàn)凯沪。
讓我們來(lái)看看如何使用mixin
類(lèi)來(lái)構(gòu)造視圖第焰。 這里是我們的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)
我們現(xiàn)在花一點(diǎn)時(shí)間來(lái)解釋下現(xiàn)在是個(gè)什么狀況妨马。我們使用了GenericAPIView
來(lái)構(gòu)建視圖挺举,并添加了ListModelMixin
和CreateModelMixin
mixins
這個(gè)基類(lèi)提供了這些核心功能,并且mixins
類(lèi)提供了.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
類(lèi)來(lái)提供核心功能滤淳,然后我們添加mixins
類(lèi)提供的.retrive()
梧喷,.update()
,.destroy()
操作脖咐。
3. 使用通用的基于類(lèi)的視圖
使用mixins
類(lèi)我們使用了更少的代碼來(lái)重寫(xiě)了我們的視圖铺敌,REST Framework
已經(jīng)提供了一組已經(jīng)混合了的通用視圖,我們可以使用它來(lái)簡(jiǎn)化我們的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
是不是感覺(jué)很不錯(cuò)偿凭,我們只使用了很少很少的代碼,而且我們的代碼看起來(lái)很干凈派歌,這很Django
接下來(lái)弯囊,我們將來(lái)討論教程的第4章,我們將介紹如何處理我們API的身份驗(yàn)證和權(quán)限胶果。
謝謝各位閱讀匾嘱,并歡迎各位留下寶貴意見(jiàn)