1. 程式人生 > 實用技巧 >drf之檢視元件

drf之檢視元件

兩個檢視基類APIView、GenericAPIView

1、APIView類:

APIView是REST framework提供的所有檢視的基類,繼承自Django的View父類。

APIViewView的不同之處在於:

  • 傳入到檢視方法中的是REST framework的Request物件,而不是Django的HttpRequeset物件;
  • 檢視方法可以返回REST framework的Response物件,檢視會為響應資料設定(render)符合前端要求的格式;
  • 任何APIException異常都會被捕獲到,並且處理成合適的響應資訊;
  • 在進行dispatch()分發前,會對請求進行身份認證、許可權檢查、流量控制。

支援定義的屬性

  • authentication_classes列表或元祖,身份認證類
  • permissoin_classes列表或元祖,許可權檢查類
  • throttle_classes列表或元祖,流量控制類

基於APIView類寫的介面:

class BooksView(APIView):
    def get(self, request):
        book_list = Book.objects.all()
        book_ser = Bookserialisers(book_list, many=True)
        return Response(book_ser.data)

    
def post(self, request): book_ser = Bookserialisers(data=request.data) if book_ser.is_valid(): book_ser.save() return Response(book_ser.data) else: return Response({'code': '101', 'msg': '新增失敗', 'data': book_ser.errors}) class BookView(APIView):
def get(self, request, pk): book = Book.objects.filter(pk=pk).first() book_ser = Bookserialisers(book) return Response(book_ser.data) def put(self, request, pk): book = Book.objects.filter(pk=pk).first() book_ser = Bookserialisers(instance=book, data=request.data) if book_ser.is_valid(): book_ser.save() return Response(book_ser.data) else: return Response(book_ser.errors) def delete(self, request, pk): ret = Book.objects.filter(pk=pk).delete() return Response({'status': 100, 'msg': '刪除成功'})

2、GenericAPIView

(1)繼承APIView類,加入了操作序列化器和資料庫操作方法。基於GenericAPIView類的介面如下

from rest_framework.generics import GenericAPIView
'''
屬性
queryset:指明使用的資料查詢集
serializer_class:指明當前檢視函式使用的序列化器
方法:
get_queryset():返回的是資料庫查詢結果集,一般資料查詢結果有多條資料的時候使用該方法
get_object():返回的是資料庫查詢結果(單條),一般是查詢結果資料只用一條的時候使用該方法。
get_serializer:返回序列化物件
'''
# GenericAPIView介面
class Books1View(GenericAPIView):
    queryset = Book.objects
    serializer_class = Bookserialisers

    def get(self, request):
        #get_queryset()方法返回的是資料庫查詢結果集
        book = self.get_queryset()
        #返回序列化物件
        book_ser = self.get_serializer(book, many=True)
        return Response(book_ser.data)

    def post(self, request):
        book_ser = self.get_serializer(data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'msg': '新增失敗'})
class Book1View(GenericAPIView):
    queryset = Book.objects
    serializer_class = Bookserialisers

    def get(self, request, pk):
        #get_boject()返回的是資料庫查詢結果。
        book = self.get_object()
        book_ser = self.get_serializer(book)
        return Response(book_ser.data)

    def put(self, request, pk):
        book = self.get_object()
        book_ser = self.get_serializer(instance=book, data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response(book_ser.errors)

    def delete(self, request, pk):
        book = self.get_object().delete()
        return Response({'msg': '刪除成功'})

基於GenericAPIView類的五個檢視擴充套件類

from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, RetrieveModelMixin,DestroyModelMixin
from rest_framework.generics import ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView

這五個類將5個介面分別進行了封裝

類名 方法(需要傳引數) 請求方法
ListModelMixin list() get(查詢所有)
CreateModelMixin create() post
UpdateModelMixin update() put
RetrieveModelMixin retrieve() get(查詢單個)
DestroyModelMixin destroy() delete

基於擴充套件類的介面

# 五個擴充套件類
class Books2View(ListModelMixin, GenericAPIView, CreateModelMixin):
    queryset = Book.objects
    serializer_class = Bookserialisers

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)
class Book2View(GenericAPIView, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin):
    queryset = Book.objects
    serializer_class = Bookserialisers

    def get(self, request, pk):
        return self.retrieve(request, pk)

    def put(self, request, pk):
        return self.update(request, pk)

    def delete(self, request, pk):
        return self.destroy(request, pk)

GenericAPIView九個功能子類檢視:

類名 方法:
ListAPIView get()
CreateAPIView create()
RetrieveUpdateAPIView retrieve()
DestroyAPIView delete()
UpdateAPIView update
ListCreateAPIView list(),create(),patch()
RetrieveUpdateAPIView retrieve(),update(),patch()
RetrieveDestroyAPIView retrieve(),destroy(),patch()
RetrieveUpdateDestroyAPIView retrieve(),update(),destroy(),patch()

#查詢所有書籍和新增書籍
class Books_zuhe(ListCreateAPIView):
    queryset = Book.objects
    serializer_class = Bookserialisers
#書籍的查刪改
class Book_zuhe(RetrieveUpdateDestroyAPIView):
    queryset = Book.objects
    serializer_class = Bookserialisers

檢視集

ModelViewSet繼承了GenericViewSet,提供了action方法。除了預設的五個介面方法外,還可以自己定義新的方法:

路由檔案urls

urlpatterns = [

url(r'^books/latest/$', views.BookViewSet.as_view({'get': 'latest'})),
    url(r'^books/(?P<pk>\d+)/$', views.BookViewSet.as_view({'get': 'retrieve'})),
    url(r'books3/', views.BookViewSet.as_view(actions={'get':'list','post':'create'})),
    url(r'book3/(?P<pk>\d+)', views.BookViewSet.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
]

基於ModelViewSet類介面程式碼

#ModelViewSet介面
class BookViewSet(ModelViewSet):
    queryset = Book.objects
    serializer_class = Bookserialisers

    def latest(self, request):
        """
        返回最新的圖書資訊
        """
        book = Book.objects.latest('id')
        serializer = self.get_serializer(book)
        return Response(serializer.data)

    def read(self, request, pk):
        """
        修改圖書的閱讀量資料
        """
        book = self.get_object()
        book.bread = request.data.get('read')
        book.save()
        serializer = self.get_serializer(book)
        return Response(serializer.data)