1.APIView
DRF框架的視圖的基類是 APIView
APIView的基本使用和View類似
-
Django默認的View請求對象是 HttpRequest,REST framework 的請求對象是 Request。
Request對象的數據是自動根據前端發送數據的格式進行解析之后的結果。
HttpRequest.GET ————> Request.query_params
HttpRequest.POST 、HttpRequest.body————> Request.data -
Django默認的View響應對象是 HttpResponse(以及子類),REST framework 的響應對象是Response。
構造方式:Response(data, status=None, template_name=None, headers=None, content_type=None)
參數說明:-
List item
-
data: 為響應准備的序列化處理后的數據;
-
status: 狀態碼,默認200;
-
template_name: 模板名稱,如果使用HTMLRenderer時需指明;
-
headers: 用於存放響應頭信息的字典;
-
content_type: 響應數據的Content-Type,通常此參數無需傳遞,REST framework會根據前端所需類型數據來設置該參數。
-
-
支持定義的屬性:
authentication_classes列表或元祖,身份認證類
permissoin_classes列表或元祖,權限檢查類
throttle_classes列表或元祖,流量控制類。 -
在APIView中仍以常規的類視圖定義方法來實現get() 、post() 或者其他請求方式的方法。如下:
''' serializers.py ''' class BookSerializer(serializers.ModelSerializer): class Meta: model = BookInfo # 設置關聯模型 model就是關聯模型 fields = '__all__' # fields設置字段 __all__表示所有字段 '''urls.py''' url(r'^center/$',views.CenterView.as_view()) ''' views.py ''' class CenterView(APIView): def get(self,request): # 以前的 HttpRequest.GET # 現在的 # /center/?a=100&b=python params = request.query_params print(params) # 響應不同的第一個 dict = { 'name':'hello' } # return JsonResponse(dict) return Response(dict) # return HttpResponse('get') def post(self,request): # 以前的 HttpRequest.POST,HttpRequest.body # 現在 # form 表單提交數據 data = request.data print(data) return HttpResponse('post')
2.實例:使用APIView實現列表功能
'''urls.py''' url(r'^books/$',views.BookListAPIView.as_view()) '''views.py''' class BookListAPIView(APIView): '''書籍列表頁''' def get(self,request): # 1.獲取所有書籍 books = BookInfo.objects.all() # 2.通過序列化器的轉換(模型轉換為JSON) serializer = BookSerializer(book,many=True) # 3.返回響應 return Response(serializer.data) def post(self,request): # 1.接收參數 data = request.data # 2.驗證參數(序列化器的校驗) serializer = BookSerializer(data=data) serializer.is_valid(raise_exception=True) # 3.數據入庫 serializer.save() # 4.返回響應 return Response(serializer.data)
3.GenericAPIView
-
GenericAPIView是繼承自APIView,GenericAPIView肯定在APIView的基礎上 封裝了一些屬性和方法:增加了對於列表視圖和詳情視圖可能用到的通用方法和屬性的支持
屬性:
queryset 設置結果集
serializer_class 設置序列化器
lookup_field 查詢指定的對象方法:
get_queryset(self) 返回視圖使用的查詢集
get_serializer(self,_args, *_kwargs) 返回序列化器對象
get_object(self) 返回詳情視圖所需的模型類數據對象 -
通常使用時,可搭配一個或多個擴展類(Mixin類,詳見4.)
##########GenericAPIView列表視圖################## '''urls.py''' url(r'^books/$',views.BookListGenericAPIView.as_view()) '''views.py''' class BookListGenericAPIView(GenericAPIView): '''列表視圖''' # 查詢結果集 queryset = BookInfo.objects.all() # 序列化器類 serializer_class = BookSerializer def get(self,request): # 1.獲取所有書籍 # books = BookInfo.objects.all() # 上面寫法也可以,但屬性就白白浪費了,沒有充分發揮屬性的作用 books = self.get_queryset() # 2.創建序列化器 # serializer = BookSerializer(books,many=True) # 以上寫法也可可以,但是還是沒有發揮屬性的作用 # get_serializer()相當於BookSerializer() serializer = self.get_serializer(book,many=True) # 3.返回響應 return Response(serializer.data) def post(self,request): # 1.獲取參數 data = request.data # 2.創建序列化器 serializer = self.get_serializer(data=data) # 3.校驗 serializer.is_valid(raise_exception=True) # 4.保存 serializer.save() # 5.返回響應 return Response(serializer.data) class BookDetailGenericAPIView(GenericAPIView): '''詳情視圖''' # 查詢結果集 queryset = BookInfo.objects.all() # 序列化器類 serializer_class = BookSerializer # 默認是pk 修改后以下參數都要變 lookup_field = 'id' def get(self,request,id): # 1.獲取對象 book = self.get_object() # 2.創建序列化器 serializer = self.get_serializer(book) # 3.返回響應 return Response(serializer.data) def put(self,request,id): # 1.獲取對象 book = self.get_object() # 2.接收參數 data = request.data # 3.創建序列化器 serializer = self.get_serializer(instance=book,data=data) # 4.驗證 serializer.is_valid(raise_exception=True) # 5.保存(更新) serializer.save() # 3.返回響應 return Response(serializer.data) def delete(self,request,pk): # 1.獲取對象 book = self.get_object() # 2.刪除 book.delete() # 3.返回響應 return Response(status=status.HTTP_204_NO_CONTENT)
4.GenericAPIView和Mixin配合使用
mixin類提供用於提供基本視圖行為的操作。請注意,mixin類提供了操作方法,而不是直接定義處理程序方法,例如.get()和.post()。這允許更靈活的行為組合。
- ListModelMixin
提供一種.list(request, *args, **kwargs)實現列出查詢集的方法。 - CreateModelMixin
提供.create(request, *args, **kwargs)實現創建和保存新模型實例的方法。 - RetrieveModelMixin
提供一種.retrieve(request, *args, **kwargs)方法 - UpdateModelMixin
提供.update(request, *args, **kwargs)實現更新和保存現有模型實例的方法。 - DestroyModelMixin
提供一種.destroy(request, *args, **kwargs)實現刪除現有模型實例的方法。
'''urls.py''' url(r'^booklist/$',views.BookListGenericMixinAPIView.as_view()) '''views.py''' # ListModelMixin 獲取全部對象(列表) # CreateModelMixin 新增資源 # RetrieveModelMixin 獲取一個資源 # UpdateModelMixin 更新一個資源 # DestoryModelMixin 刪除一個資源 class BookListGenericMixinAPIView(ListModelMixin,CreateModelMixin,GenericAPIView): # 查詢結果集 queryset = BookInfo.objects.all() # 序列化器類 serializer_class = BookSerializer def get(self,request): return self.list(request) def post(self,request): return self.create(request) def post(self,request): return self.create(request) class BookDetailGenericMixinAPIView(R,U,D): def get(self,request): return self.retrieve(request) def put(self,request): return self.update(request) def delete(self,request): return self.destroy(request)
6.三級視圖
-
CreateAPIView
提供post方法處理程序。 -
ListAPIView
用於只讀端點以表示模型實例的集合。
提供get方法處理程序。 -
RetrieveAPIView
用於表示單個模型實例的只讀端點。
提供get方法處理程序。 -
DestroyAPIView
用於單個模型實例的僅刪除端點。
提供delete方法處理程序。 -
UpdateAPIView
用於單個模型實例的僅更新端點。
提供put和patch方法處理程序。 -
ListCreateAPIView
用於讀寫端點以表示模型實例的集合。
提供get和post方法處理程序。 -
RetrieveUpdateAPIView
用於讀取或更新端點以表示單個模型實例。
提供get,put並且patch方法處理。 -
RetrieveDestroyAPIView
用於讀取或刪除端點以表示單個模型實例。
提供get和delete方法處理程序。 -
RetrieveUpdateDestroyAPIView
用於讀寫 - 刪除端點以表示單個模型實例。
提供get,put,patch和delete方法處理。
'''urls.py''' url(r'^booklist/$',views.Book2ListAPIView.as_view()) '''views.py''' class Book2ListAPIView(ListAPIView): # 查詢結果集 queryset = BookInfo.objects.all() # 序列化器類 serializer_class = BookSerializer
7.視圖集Viewset
-
APIView,GenericAPIView,ListAPIView 都是繼承自View
繼承自View的類視圖,只能定義相同的一個函數名,例如:只能定義一個get,post方法 -
列表視圖中 設置了 queryset,serializer_class get,post
詳情視圖中也設置了 queryset,serializer_class get,put,delete
能否將這兩個視圖合並???
我們是可以將 列表和詳情視圖 組合到一起的,稱之為 視圖集 ViewSet
它不提供任何方法處理程序( 如get(),post() ),而是提供了諸如list() create()之類的操作
class BookViewSet(ViewSet): # get def list(self,request): queryset = BookInfo.objects.all() serializer = BookInfoSerializer(queryset,many=True) return Response(serializer.data) # get def retrieve(self,request,pk=None): queryset = BookInfo.objects.all() user = get_object_or_404(queryset, pk=pk) serializer = BookInfoSerializer(user) return Response(serializer.data) '''urls.py''' # 繼承自 ViewSet的url 可以自動生成 from rest_framework.routers import DefaultRouter,SimpleRouter # Router:的相同點 都是可以自動生成url # Router:的不同點 # DefaultRouter 可以在根路由下顯示 # SimpleRouter 不可以在根路由下顯示,且會報404 # 1.創建router對象 router = DefaultRouter() # 2.設置正則 # router的原理 # router 會自動生成兩個url 一個是列表視圖的url 另一個是詳情視圖的url # 參數1:正則, 只需要設置列表視圖和詳情視圖公共的部分 # 例如: booklist/是列表視圖 # booklist/id 是詳情視圖 # 公共部分是 booklist 不包括/ # 參數2:視圖集 # 參數3:base_name 只是我們名字url name的一個前綴 # 例如:列表視圖的名字: base_name-list book-list # 詳情視圖的名字: base_name-detail book-detail router.register(r'booklist',views.BookModelViewset,base_name='book') # 3.將自動生成的url 添加到 urlpatterns中 # router.urls urls 這個屬性 存放了自動生成的url urlpatterns += router.urls # ModelViewSet 其實就是繼承自 GenericAPIView,同時繼承了5個擴展 class BookModelViewset(ModelViewSet): queryset = BookInfo.objects.all() serializer_class = BookSerializer