日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

drf4 视图与路由组件

發(fā)布時間:2024/9/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 drf4 视图与路由组件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

APIView和View的區(qū)別

不管是View還是APIView最開始調(diào)用的都是as_view()

APIView繼承了View, 并且執(zhí)行了View中的as_view()方法,最后把view返回了,用csrf_exempt()方法包裹后去掉了csrf的認(rèn)證。

?

在View中的as_view方法返回了view函數(shù),而view函數(shù)執(zhí)行了self.dispatch()方法,但是這里的dispatch方法應(yīng)該是我們APIView中的

去initialize_request中看下把什么賦值給了request,并且賦值給了self.request, 也就是我們在視圖中用的request.xxx到底是什么~~

看到,這個方法返回的是Request這個類的實例對象~~我們注意我們看下這個Request類中的第一個參數(shù)request,是我們走我們django的時候的原來的request

我們看到了,這個Request類把原來的request賦值給了self._request, 也就是說以后_request是我們老的request,新的request是我們這個Request類

我們用了rest_framework框架以后,我們的request是重新封裝的Request類

request.query_params 存放的是我們get請求的參數(shù)

request.data 存放的是我們所有的數(shù)據(jù),包括post請求的以及put,patch請求

相比原來的django的request,我們現(xiàn)在的request更加精簡,清晰了

現(xiàn)在我們知道了APIView和View的一些區(qū)別

視圖的第一次封裝

GenericAPIView 是對 APIView 的封裝 xxxMixin 是對處理的各種請求方法的封裝 class BookView(APIView):def get(self, request):query_set = Book.objects.all()book_ser = BookSerializer(query_set, many=True)return Response(book_ser.data)def post(self, request):query_set = request.databook_ser = BookSerializer(data=query_set)if book_ser.is_valid():book_ser.save()return Response(book_ser.validated_data)else:return Response(book_ser.errors)class BookEditView(APIView):def get(self, request, id):query_set = Book.objects.filter(id=id).first()book_ser = BookSerializer(query_set)return Response(book_ser.data)def patch(self, request, id):query_set = Book.objects.filter(id=id).first()book_ser = BookSerializer(query_set, data=request.data, partial=True)if book_ser.is_valid():book_ser.save()return Response(book_ser.validated_data)else:return Response(book_ser.errors)def delete(self, request, id):query_set = Book.objects.filter(id=id).first()if query_set:query_set.delete()return Response("")else:return Response("刪除的書籍不存在")APIView視圖 APIView from rest_framework.views import APIView from rest_framework.viewsets import GenericViewSet from rest_framework.response import Response from .serializers import BookSerializerclass GenericAPIView(APIView):query_set = Noneserializer_class = Nonedef get_queryset(self):return self.query_setdef get_serializer(self, *args, **kwargs):return self.serializer_class(*args, **kwargs)class ListModelMixin(object):def list(self, request):queryset = self.get_queryset()ret = self.get_serializer(queryset, many=True)return Response(ret.data)class CreateModelMixin(object):def create(self, request):serializer = self.get_serializer(data=request.data)if serializer.is_valid():serializer.save()return Response(serializer.data)else:return Response(serializer.errors)class RetrieveModelMixin(object):def retrieve(self, request, id):book_obj = self.get_queryset().filter(id=id).first()ret = self.get_serializer(book_obj)return Response(ret.data)class UpdateModelMixin(object):def update(self, request, id):book_obj = self.get_queryset().filter(id=id).first()serializer = self.get_serializer(book_obj, data=request.data, partial=True)if serializer.is_valid():serializer.save()return Response(serializer.data)else:return Response(serializer.errors)class DestroyModelMixin(object):def destroy(self, request, id):book_obj = self.get_queryset().filter(id=id).first()book_obj.delete()return Response("")class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):passclass RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):pass# class BookView(GenericAPIView, ListModelMixin, CreateModelMixin): class BookView(ListCreateAPIView):query_set = Book.objects.all() # 操作的表的對象serializer_class = BookSerializer # 序列化的類def get(self, request):# book_obj = Book.objects.first()# ret = BookSerializer(book_obj)# book_list = Book.objects.all()# book_list = self.get_queryset()# ret = self.get_serializer(book_list, many=True)# return Response(ret.data)return self.list(request)def post(self, request):# print(request.data)# serializer = BookSerializer(data=request.data)# if serializer.is_valid():# serializer.save()# return Response(serializer.data)# else:# return Response(serializer.errors)return self.create(request)# class BookEditView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): class BookEditView(RetrieveUpdateDestroyAPIView):query_set = Book.objects.all()serializer_class = BookSerializerdef get(self, request, id):# book_obj = Book.objects.filter(id=id).first()# ret = BookSerializer(book_obj)# return Response(ret.data)return self.retrieve(request, id)def put(self, request, id):# book_obj = Book.objects.filter(id=id).first()# serializer = BookSerializer(book_obj, data=request.data, partial=True)# if serializer.is_valid():# serializer.save()# return Response(serializer.data)# else:# return Response(serializer.errors)return self.update(request, id)def delete(self, request, id):# book_obj = Book.objects.filter(id=id).first()# book_obj.delete()# return Response("")return self.destroy(request, id) 視圖的第一次封裝

視圖的第二次封裝

class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):passclass RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):passclass BookView(ListCreateAPIView):passclass BookEditView(RetrieveUpdateDestroyAPIView):pass # 上面我們寫的繼承類太長了~~我們再改改class ListCreateAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):passclass RetrieveUpdateDestroyAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):passclass BookView(ListCreateAPIView):queryset = Book.objects.all()serializer_class = BookSerializerdef get(self, request, *args, **kwargs):return self.list(request, *args, **kwargs)def post(self, request, *args, **kwargs):return self.create(request, *args, **kwargs)class BookEditView(RetrieveUpdateDestroyAPIView):queryset = Book.objects.all()serializer_class = BookSerializerdef get(self, request, id, *args, **kwargs):return self.retrieve(request, id, *args, **kwargs)def patch(self, request, id, *args, **kwargs):return self.update(request, id, *args, **kwargs)def delete(self, request, id, *args, **kwargs):return self.delete(request, id, *args, **kwargs)第二次封裝 第二次封裝

視圖的第三次封裝

ViewSetMixin

actions這個默認(rèn)參數(shù)其實就是我們路由可以進行傳參了

下面這個循環(huán),可以看出,我們要傳的參數(shù)是一個字段~key應(yīng)該是我們的請求方式,value應(yīng)該對應(yīng)我們處理的方法

這樣我們每個視圖就不用在寫函數(shù)了,因為已經(jīng)和內(nèi)部實現(xiàn)的函數(shù)相對應(yīng)了

因為是按照請求的方式不同反回的結(jié)果,所有第二次有兩個視圖函數(shù)

現(xiàn)在指定一個視圖函數(shù)

# 視圖類傳參,不同的請求對應(yīng)不同的方法path('list', BookModelViewSet.as_view({"get": "list", "post": "create"})),path('retrieve/<int:pk>', BookModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

注意一點,用框架封裝的視圖,我們url上的那個關(guān)鍵字參數(shù)要用pk,系統(tǒng)默認(rèn)的

# class ViewSetMixin(object): # def as_view(self): # """ # 按照我們參數(shù)指定的去匹配 對應(yīng)的方法 # get-->list # :return: 不用我們?nèi)?#xff0c;框架有 # """

ViewSetMixin 請求分發(fā)方法的原理,將不同的請求設(shè)置為不同的方法

from rest_framework.viewsets import ViewSetMixin# class BookView(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView): # queryset = Book.objects.all() # serializer_class = BookSerializer# 如果我們再定義一個類 class ModelViewSet(ViewSetMixin, ListCreateAPIView, RetrieveUpdateDestroyAPIView):passclass BookView(ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializer第三次封裝 第三次封裝 from rest_framework.viewsets import ViewSetMixinclass ModelViewSet(ViewSetMixin, GenericAPIView, ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):pass# from rest_framework.viewsets import ModelViewSet # 框架內(nèi)部已經(jīng)實現(xiàn)了的,可以直接導(dǎo)入 # class BookModelViewSet(ModelViewSet): query_set = Book.objects.all() 自己封裝的query_set
? # queryset = Book.objects.all() # 框架的是queryset
serializer_class = BookSerializer from rest_framework import views # APIView
from rest_framework import generics # GenericAPIView, 組合類
from rest_framework import mixins #混合繼承類
from rest_framework import viewsets # ViewSetMixin 分發(fā)請求的類

我們現(xiàn)在的視圖就只要寫兩行就可以了

用框架的時

路由為

path('retrieve/<int:pk>', BookModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

前面自己定義的是id,用框架時注意修改過來

path('retrieve/<int:id>', BookModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})), # 視圖類傳參.只有業(yè)務(wù)需求匹配性很強才用。通常情況下不這么用容易暴露接口# path('list', BookModelViewSet.as_view({"get": "list", "post": "create"})),# path('retrieve/<int:id>', BookModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

繼承順序

DRF的路由

from django.urls import path, include from .views import BookView, BookEditView, BookModelViewSet from rest_framework.routers import DefaultRouterrouter = DefaultRouter()router.register(r"", BookModelViewSet) # 不能 加$ r"$"urlpatterns = [# path('list', BookView.as_view()),# path('retrieve/<int:id>', BookEditView.as_view()),# 視圖類傳參.只有業(yè)務(wù)需求匹配性很強才用。通常情況下不這么用容易暴露接口# path('list', BookModelViewSet.as_view({"get": "list", "post": "create"})),# path('retrieve/<int:id>', BookModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),]urlpatterns += router.urlsDefaultRouter DRF的路由

通過框架我們可以把路由視圖都變的非常簡單,但是需要自定制的時候還是需要我們自己用APIView寫

當(dāng)不需要那么多路由的時候,也不要用這種路由注冊

總之,一切按照業(yè)務(wù)需要去用

總結(jié)

以上是生活随笔為你收集整理的drf4 视图与路由组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。