Django通用檢視APIView和檢視集ViewSet的介紹和使用
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