【DRF檢視】
阿新 • • 發佈:2018-12-25
目錄
請結合【DRF序列化】此文獻中的資料檔案及序列化檔案來閱讀如下程式碼.
DRF檢視為我們提供了非常簡便的方法——內建了增刪改查等一系列的操作.
我們只需在url中指定對應的方法,檢視繼承內建方法的類,即可實現兩三行程式碼搞定一個請求.
@
*
我們先看看仿照內建方法實現的**
APIView檢視檔案:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.viewsets import ViewSetMixin """ ===================== 一層封裝 ===================== """ class GenericAPIView(APIView): queryset = None serializer_class = None def get_queryset(self): """用於獲取queryset的方法""" return self.queryset.all() def get_serializer(self, *args, **kwargs): """用於呼叫序列化類的方法""" return self.serializer_class(*args, **kwargs) class ListModelMixin(): """用於返回get請求所有資料的資料""" def list(self, request): queryset = self.get_queryset() # self呼叫的方法(get_queryset)是從執行此方法(list)的當前物件的類中開始找 ser_obj = self.get_serializer(queryset, many=True) # 原理同上句話 return Response(ser_obj.data) class CreateModelMixin(): """用於處理post請求發來的資料""" def create(self, request): ser_obj = self.get_serializer(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) return Response(ser_obj.errors) class RetrieveModelMixin(): """用於返回get請求查詢單條資料方法""" def retrieve(self, request, id): book_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(book_obj) return Response(ser_obj.data) class UpdateModelMixin(): """用於處理put請求發來的資料(更新資料)""" def update(self, request, id): book_obj = self.get_queryset().filter(id=id).first() ser_obj = self.get_serializer(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) return Response(ser_obj.errors) class DestroyModelMixin(): """用於刪除單條資料""" def destroy(self, request, id): book_obj = self.get_queryset().filter(id=id).first() if book_obj: book_obj.delete() return Response('') return Response('The deleted object does not exist.') """ ===================== 二層封裝 ===================== """ class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin): pass class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): pass
檢視檔案:
from .custom_mixin import ListCreateAPIView, RetrieveUpdateDestroyAPIView # 匯入上述的APIView檢視檔案 from DRFView import models from .serializers import BookSerializer # 匯入自定義的序列化檔案 class Book(ListCreateAPIView): queryset = models.Book.objects.all() # 坑:這裡的queryset只是放到快取裡了,再次取時還需要用.all()方法 serializer_class = BookSerializer def get(self, request): return self.list(request) def post(self, request): return self.create(request) class BookEdit(RetrieveUpdateDestroyAPIView): queryset = models.Book.objects.all() serializer_class = BookSerializer def get(self, request, id): return self.retrieve(request, id) def put(self, request, id): return self.update(request, id) def delete(self, request, id): return self.destroy(request, id)
改進版
urls.py檔案:
urlpatterns = [ url(r'^book/$', BookModel.as_view({'get': 'list', 'post': 'create'})), url(r'^book/(?P<id>\d+)/$', BookModelView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), ] """ 注意as_view的傳參: as_view({"請求方式": "呼叫的方法"}, {...}) 指定請求方式呼叫的方法後,框架會為我們自動執行其方法,無需在CBV中寫請求的方法了. """
APIView檢視檔案:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ViewSetMixin # 匯入DRF封裝好的APIView
""" ===================== 第一層封裝 ===================== """
class GenericAPIView(APIView):
queryset = None
serializer_class = None
def get_queryset(self):
"""用於獲取queryset的方法"""
return self.queryset.all()
def get_serializer(self, *args, **kwargs):
"""用於呼叫序列化類的方法"""
return self.serializer_class(*args, **kwargs)
class ListModelMixin():
"""用於返回get請求所有資料的資料"""
def list(self, request):
queryset = self.get_queryset() # self呼叫的方法(get_queryset)是從執行此方法(list)的當前物件的類中開始找
ser_obj = self.get_serializer(queryset, many=True) # 原理同上句話
return Response(ser_obj.data)
class CreateModelMixin():
"""用於處理post請求發來的資料"""
def create(self, request):
ser_obj = self.get_serializer(data=request.data)
if ser_obj.is_valid():
ser_obj.save()
return Response(ser_obj.validated_data)
return Response(ser_obj.errors)
class RetrieveModelMixin():
"""用於返回get請求查詢單條資料方法"""
def retrieve(self, request, id):
book_obj = self.get_queryset().filter(id=id).first()
ser_obj = self.get_serializer(book_obj)
return Response(ser_obj.data)
class UpdateModelMixin():
"""用於處理put請求發來的資料(更新資料)"""
def update(self, request, id):
book_obj = self.get_queryset().filter(id=id).first()
ser_obj = self.get_serializer(instance=book_obj, data=request.data, partial=True)
if ser_obj.is_valid():
ser_obj.save()
return Response(ser_obj.validated_data)
return Response(ser_obj.errors)
class DestroyModelMixin():
"""用於刪除單條資料"""
def destroy(self, request, id):
book_obj = self.get_queryset().filter(id=id).first()
if book_obj:
book_obj.delete()
return Response('')
return Response('The deleted object does not exist.')
""" ===================== 第二層封裝 ===================== """
class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
pass
class RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
pass
""" ===================== 第三層封裝 ===================== """
class ModelViewSet(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView):
# ViewSetMixin重寫了as_view方法,即可以傳參了.
pass
檢視檔案:
from .custom_mixin import ModelViewSet # 匯入上述的APIView檢視檔案
from DRFView import models
from .serializers import BookSerializer # 匯入自定義的序列化檔案
class BookModel(ModelViewSet):
queryset = models.Book.objects.all()
# 坑:這裡的queryset只是放到快取裡了,再次取時還需要用.all()方法
# queryset是框架能識別的,會把資料放到快取中,如果該成其它的名字則不會快取(比如query),即再此取資料時不能加.all()
serializer_class = BookSerializer
class BookModelView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializer
接下來,我們再來看看DRF為我們封裝好了的APIView用法。
***
開始使用內建檢視
第一步 按照框架的要求寫url
urlpatterns = [ url(r'^book/$', BookModel.as_view({'get': 'list', 'post': 'create'})), # 按照APIView的要求,這裡必須寫為pk,而不能寫id url(r'^book/(?P<pk>\d+)/$', BookModelView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), ] """ 注意as_view的傳參: as_view({"請求方式": "呼叫的方法"}, {...}) 指定請求方式呼叫的方法後,無需在CBV中寫請求的方法了. """
第二步 寫檢視檔案
```python
from DRFView import models
from .serializers import BookSerializer # 匯入自定義的序列化檔案
from rest_framework.viewsets import ModelViewSet # 匯入DRF封裝好的APIViewclass BookModel(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializerclass BookModelView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializer
如上步驟,我們的檢視只要寫兩行就可以了.
關於DRF檢視原始碼解析,推薦參考此文獻:https://www.cnblogs.com/GGGG-XXXX/articles/9675911.html
繼承順序圖解: