drf中的各种view,viewset
drf中的各種view,viewset
Django REST framework里有各種各樣的view,讓我有點蒙,得好好捋一捋這關系。
視圖的作用
Django用“視圖”這個概念封裝處理用戶請求并返回響應的邏輯。
視圖是一個可調用對象,它不僅可以是基于函數,也可以是基于類的。
相比較與函數,基于類的視圖有一些區別和優勢:
- 組織與特定HTTP方法相關的代碼(GET,POST等) 可以通過單獨的方法而不是條件分支來解決。
- 面向對象的技術例如Mixin(多繼承、混用)可以將代碼分解成可重用的組件。
視圖函數:
def my_view(request):if request.method == 'GET':# <view logic>return HttpResponse('result')視圖類:
class MyView(View):def get(self, request):# <view logic>return HttpResponse('result')View
Django中的View
是所有基于類的view的父類,它負責將視圖連接到URL、HTTP 方法調度(GET,POST等)和其它簡單的功能。
APIView
APIView是drf中所有view的父類,本身繼承于Django的VIew,只有簡單的調度方法和健壯檢查。
和View的不同
- 請求和返回使用的drf的Request Response而不是django的HttpRequest HttpResponse。
- 請求傳入時進行身份驗證,并在傳給處理方法前進行權限檢驗。
- 任何APIException都會被捕捉并放入合適的想要中。
使用
response返回的內容需是序列化的json。
先創建在goods包下新建serializer.py
某字段結果可能有多條時,記得加many=True!否則無法正確顯示。
class GoodsSerializer(serializers.ModelSerializer):images = GoodImagesSerializer(many=True)class Meta:model = Goodsfields = "__all__"views
因為會有多條商品信息,所以這里也要記得加many=True!否則會報錯。
class GoodsListView(APIView):# 重寫get方法 進行get訪問時會進行的處理def get(self, request):goods = Goods.objects.all()[:10]goods_list = GoodsSerializer(goods, many=True)return Response(goods_list.data)在url下配置view的訪問,別忘了這是基于類的視圖,所以要加上as_view()方法。
url(r'^GoodsListView/', GoodsListView.as_view()),GenericAPIView
GenericAPIView繼承于APIView,為標準list和detail詳情提供了常用行為,每個GenericAPIView都會和一個或多個mixin聯合使用。
屬性
- 基礎設置
- queryset 需要返回的結果集
- serializer_class 用于序列化的serializer
- lookup_field 查找單個model實例時的字段,默認為pk(主鍵)
- lookup_url_kwarg
- 分頁
- pagination_class
- 過濾
- filter_backend
使用
先在views里設置個分頁
class StandardResultsSetPagination(PageNumberPagination):page_size = 10page_size_query_param = 'page_size' # GoodsListView/?p=2&page_size=3page_query_param = 'p' # GoodsListView/?p=2max_page_size = 100 class GoodsListView(GenericAPIView, ListModelMixin):"""商品列表"""queryset = Goods.objects.all()# 序列化serializer_class = GoodsSerializer# 分頁pagination_class = StandardResultsSetPagination# 過濾 /排序、搜索filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)ordering_fields = ('add_time', )search_fields = ('name', 'goods_desc')def get(self, request, *args, **kwargs):return self.list(request, *args, **kwargs)ListAPIView
除了繼承GenericAPIView加ListModelMixin,重寫了下get方法,沒干別的事。
源碼
class ListAPIView(mixins.ListModelMixin,GenericAPIView):"""Concrete view for listing a queryset."""def get(self, request, *args, **kwargs):return self.list(request, *args, **kwargs)使用
class GoodsListView(ListAPIView):"""商品列表"""queryset = Goods.objects.all()# 序列化serializer_class = GoodsSerializer# 分頁pagination_class = StandardResultsSetPagination# 過濾 /排序、搜索filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)ordering_fields = ('add_time', )search_fields = ('name', 'goods_desc')作用就是少寫繼承,不用重寫get...
類似有:
class CreateAPIView(mixins.CreateModelMixin,GenericAPIView) class RetrieveAPIView(mixins.RetrieveModelMixin,GenericAPIView) class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,mixins.UpdateModelMixin,GenericAPIView)等等常用到的行為都被封裝了。
GenericViewSet
繼承于GenericAPIView,并提供默認的get_object,get_queryset方法和其他通用視圖基本行為,但默認情況下不包含任何操作。為了使用GenericViewSet類,您將覆蓋該類并混合所需的mixin類,或者顯式定義動作實現。
源碼
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):pass只是比GenericAPIView多了ViewSetMixin。
在ViewSetMixin里重寫了as_view方法,可以更方便的綁定actions。
使用
class GoodsListViewSet(GenericViewSet, ListModelMixin):"""商品列表"""queryset = Goods.objects.all()# 序列化serializer_class = GoodsSerializer# 分頁pagination_class = StandardResultsSetPaginationurls配置
將get請求 綁定到list() action
goods_list = GoodsListViewSet.as_view({'get': 'list' })urlpatterns = [....url(r'^goodsList/', goods_list), ]使用router
VIewSet常常和router使用,router可以自動將常用的 get綁定list,post綁定create這些操作完成。
urls中設置如下,上面的那兩個設置就不需要了。
from rest_framework.routers import DefaultRouterrouter = DefaultRouter() router.register('goodsList', GoodsListViewSet)urlpatterns = [.....url(r'^', include(router.urls)), ]ReadOnlyModelViewSet
繼承于GenericViewSet,混用RetrieveModelMixin,ListModelMixin。這樣我們就既可以用它來訪問列表,也可以用來訪問詳情。
源碼
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet):"""A viewset that provides default `list()` and `retrieve()` actions."""pass使用
class GoodsViewSet(viewsets.ReadOnlyModelViewSet):"""商品列表商品詳情"""queryset = Goods.objects.all()# 序列化serializer_class = GoodsSerializer# 分頁pagination_class = StandardResultsSetPagination綁定router
router.register('goods', GoodsViewSet)訪問接口
訪問商品列表
http://127.0.0.1:8000/goods/
訪問商品詳情
http://127.0.0.1:8000/goods/1
轉載于:https://www.cnblogs.com/hehecat/p/9349427.html
總結
以上是生活随笔為你收集整理的drf中的各种view,viewset的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MFC对话框控件访问的七种方式
- 下一篇: 什么是缓存击穿?