我们也可以使用基于类的视图编写我们的 API 视图,而不是基于函数的视图。我们将看到这是一个强大的模式,允许我们重用常用功能,并帮助我们保持代码 DRY(Don't repeat yourself)。
我们将首先将根视图重写为基于类的视图。所有这些都是对 apis.py
文件的重构。
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from myApp.models import Book
from myApp.serializers import BookSerializer
class BookList(APIView):
# 显示所有 book
def get(self, request, format=None):
book_list = Book.objects.all()
book_list_serializer = BookSerializer(book_list, many=True)
return Response(book_list_serializer.data)
# 添加一个 book
def post(self, request, format=None):
book_serializer = BookSerializer(data=request.data)
if book_serializer.is_valid():
book_serializer.save()
return Response(book_serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(book_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
我们还需要重构我们的 urls.py
,现在我们使用基于类的视图。
......
from myApp import apis
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
......
url(r'^api/$', apis.BookList.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
好了,我们完成了。如果你启动服务,那么它应该像之前一样可以运行。
下面我们再来构建单独一个 book 对象的 API,赋予其更多的 HTTP 方法并实现增删查改操作。
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from myApp.models import Book
from myApp.serializers import BookSerializer
class BookDetail(APIView):
# 获取一个 book 对象
def get_object(self, pk):
try:
return Book.objects.get(pk=pk)
except Book.DoesNotExist:
raise Http404
# 返回某个 book 对象的 API
# pk 是从 URL 传进来的参数
def get(self, request, pk, format=None):
book = self.get_object(pk)
book_serializer = BookSerializer(book)
return Response(book_serializer.data)
# 修改一个 book 对象
def put(self, request, pk, format=None):
book = self.get_object(pk)
book_serializer = BookSerializer(book, data=request.data)
if book_serializer.is_valid():
book_serializer.save()
return Response(book_serializer.data)
else:
return Response(book_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# 删除一个 book 对象
def delete(self, request, pk, format=None):
book = self.get_object(pk)
book.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
编写 urls.py
:
from django.conf.urls import url
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from myApp import apis
from myApp.views import index
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/$', apis.BookList.as_view()),
url(r'^api/book/(?P<pk>[0-9]+)/$', apis.BookDetail.as_view()),
url(r'^index/', index),
]
urlpatterns = format_suffix_patterns(urlpatterns)
现在主键为 1 的 book 对象 API就是:http://127.0.0.1:8000/api/book/1/