DRF框架的檢視簡析
首先我們明確REST介面開發的核心任務
在開發REST API介面時,檢視中做的最主要有三件事:
- 將請求的資料(如JSON格式)轉換為模型類物件
- 操作資料庫
- 將模型類物件轉換為響應的資料(如JSON格式)
一:使用Django開發REST 介面
資料的獲取和返回格式的組織,都要開發人員自己編寫。返回物件為HttpResponse和JsonResponse等一些子類物件,檢視類繼承自View
class BooksView(View): """ 查詢所有圖書 """ def get(self, request): """ 查詢所有圖書 路由:GET /books/ """ queryset = BookInfo.objects.all() book_list = [] for book in queryset: book_list.append({ 'id': book.id, 'btitle': book.btitle, 'bpub_date': book.bpub_date, 'bread': book.bread, 'bcomment': book.bcomment, 'image': book.image.url if book.image else '' }) return JsonResponse(book_list, safe=False)
附:響應物件要帶上狀態碼201(新建、修改), 204(刪除), 查詢不用加status 會自動返回200(成功)、404(失敗)
二:使用Django REST framework(DRF)框架來開發REST介面
想對於Django開發此介面 來看看DRF框架做的逐步封裝簡化
1.序列化器的引入:對資料物件進行轉換的操作不再需要開發人員去完成,且包含了對資料的驗證功能。
class BooksView(View): """查詢所有圖書資訊 """ def get(self, request): """ 查詢所有圖書 路由:GET /books/ """ books = BookInfo.objects.all() book_serializer = BookInfoSerializer(books, many=True) book_dict = book_serializer.data print(book_dict) return JsonResponse(book_dict, safe=False)
2.檢視類的封裝拓展:
2.1)兩個API檢視基類(繼承自Django的View類) [程式碼體現在Response的簡便]
"""DRF框架的APIView類、GenericAPIView類,和django中View主要的不同就是請求物件和響應物件不同"""
request:
request.data返回解析之後的請求體資料
request.query_params
與Django標準的request.GET
相同,獲取查詢字串。
Response:
REST framework提供了一個響應類Response
,使用該類構造響應物件時,響應的具體資料內容會被轉換(render渲染)成符合前端需求的型別, 構造方式如下:
Response(data, status=None, template_name=None, headers=None, content_type=None)
繼承自APIView的檢視程式碼:
class BooksAPIView(APIView):
"""查詢所有圖書資訊
"""
def get(self, request):
"""
查詢所有圖書
路由:GET /books/
"""
books = BookInfo.objects.all()
book_serializer = BookInfoSerializer(books, many=True)
book_dict = book_serializer.data
print(book_dict)
return Response(book_dict) # safe=False不需要寫了
2.2) GenericAPIView類 繼承自APIView,主要增加了操作序列化器和資料庫查詢的方法 [程式碼體現在資料的操作和方法的簡便],一般和5個Mixin拓展類配合使用,為他們提供方法支援。5個擴充套件類:List、Create、Retrieve、Update、DestroyModelMixin (前面幾個省略一點 :))
from rest_framework.mixins import ListModelMixin
from rest_framework.generics import GenericAPIView
class BooksListView(ListModelMixin, GenericAPIView):
"""只用指明資料模型類queryset
序列化器serializer_class
資料的操作也簡化了,不在需要開發人員去進行序列化器的操作了
"""
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def get(self, request):
return self.list(request)
2.3) 繼承自Mixin擴充套件類和GenericAPIView的子類可用檢視 [程式碼體現在方法都不用寫了],CreateAPIView、ListAPIView、Retrieve、Update、Destroy、
RetrieveUpdate、RetrieveUpdateDestrop (後面省略了APIView :))
from rest_framework.generics import ListAPIView
# ListAPIView 繼承自GenericAPIView, ListModelMixin
class BooksListAPIView(ListAPIView): # 可使用ListCreateAPIView
"""此時的檢視只用指定兩個屬性,方法都不用寫了
但是帶pk和不帶pk的還是要分兩個檢視類編寫
"""
queryset = HeroInfo.objects.all()
serializer_class = HeroInfoSerializer
2.4) 檢視集ViewSet,使用檢視集,可以將一系列相關的邏輯都放到一個類裡面了 [程式碼主要體現在只用寫一個檢視類],不需要再使用兩個檢視類來放不同的邏輯程式碼。但是設定路由比較特別
檢視程式碼:
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from rest_framework.decorators import action
class BooksViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin,..., GenericViewSet):
"""查詢多個、查詢單個、新增、修改的邏輯都在檢視集裡面所包含"""
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
路由設定:
urlpatterns = [
url(r'^books/$', views.BooksViewSet.as_view({'get': 'list'})),
url(r'^books/(?P<pk>\d+)/$', views.BooksViewSet.as_view({'get': 'retrieve'})),
]
2.5) 終極簡便檢視集ModelViewSet [程式碼體現在繼承類不用寫那麼多了,但路由的配置也比較特別],繼承自GenericViewSet,同時包括了
ListModelMixin、RetrieveModelMixin......
檢視程式碼:
from rest_framework.viewsets import ModelViewSet
class BooksModelViewSet(ModelViewSet):
queryset = HeroInfo.objects.all()
serializer_class = HeroInfoSerializer
路由:Routrs
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'books', BookInfoViewSet, base_name='book')
urlpatterns = [
...
]
urlpatterns += router.urls
register(prefix, viewset, base_name)
- prefix 該檢視集的路由字首
- viewset 檢視集
- base_name 路由名稱的字首