【DRF-12】rest-framework之路由

Tony_xiao發表於2024-06-05
  • 路由控制介紹:

    • 我們之前一直接觸的路由是最基本的形式, 就是我們下面介紹的第一種方式的自定義路由, 無論是FBV還是CBV, 都可以使用這用方式來設定路由來設定請求來的時候對應響應檢視的函式或者檢視類
    • 當我們使用封裝了的檢視類處理程式碼的時候, 我們就可以使用對應的半自動路由來對路由進行設定, 這時我們可以在路由中傳入一個字典, 在字典中使用key:value的形式來設定請求對應的檢視類中的處理方法, 具體的使用見下面的半自動路由配置
    • 全自動路由配置是在路由層藉助了routers來生成相應的物件來自動生成路由, 全自動路由使用的較少, 還是那句話, 本身封裝的程度越高, 相應的可擴充性就越差
  • 自定義路由(原始方式)

    • 路由設定
from django.urls import path,re_path
from api import views

urlpatterns = [
    re_path(r'^(?P<version>[v1|v2]+)/books/$', views.BookView.as_view()),
    re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)$', views.BookDetailView.as_view()),
]
  • 檢視
from django.shortcuts import render,HttpResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.versioning import URLPathVersioning,QueryParameterVersioning

class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

class BookView(APIView):
    # 獲取所有書籍資訊
    def get(self,request,*args,**kwargs):
        obj = models.Book.objects.all()
        ser = BookModelSerializer(instance=obj,many=True)
        return Response(ser.data)

    # 新增書籍資訊
    def post(self, request, *args, **kwargs):
        ser = BookModelSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return HttpResponse("提交成功")
        else:
            return HttpResponse(ser.errors)


class BookDetailView(APIView):
    # 獲取單個書籍資料
    def get(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        obj = models.Book.objects.filter(id=pk).first()
        ser = BookModelSerializer(instance=obj,many=False)
        return Response(ser.data)

    # 刪除單個書籍
    def delete(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        models.Book.objects.filter(id=pk).delete()
        return Response('刪除成功')

    # 更新書籍資訊
    def put(self,request,*args,**kwargs):
        pk = kwargs.get('pk')
        obj = models.Book.objects.filter(id=pk).first()
        ser = BookModelSerializer(data=request.data,instance=obj)
        if ser.is_valid():
            ser.save()
            return HttpResponse("更新成功")
        else:
            return Response(ser.errors)
  • 半自動路由(檢視類繼承ModelViewSet)
    • 半自動路由的使用場景是比較多的, 這裡繼承ModelViewSet, 實際最終還是來自於ViewSetMixin, 半自動路由正式和它配合使用的
    • 半自動路由可以在路由層傳入字典, 在字典中規定對應請求在是檢視類中處理方法, 這樣就解決了, 兩個get請求需要獲取不同資料的需求, 也正式這一點, 使用半自動路由的時候, 可以在檢視類中可以自己自由定製對應請求在檢視類中處理方法的名字, 不用再拘束於get請求要檢視類中的處理方法就必須是get這樣的約束.
    • 路由
from django.urls import path,re_path
from api import views

urlpatterns = [
    # re_path(r'^(?P<version>[v1|v2]+)/books/$', views.BookView.as_view()),
    # re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)$', views.BookDetailView.as_view()),
    re_path(r'^(?P<version>[v1|v2]+)/book/$', views.BookView.as_view({'get':'list','post':'create'})),
    re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)/$', views.BookView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
]
  • 檢視
from rest_framework.viewsets import ModelViewSet

class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

class BookView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
  • 全自動路由
    • 全自動路由在路由層由routers例項化出的物件輔助來完成自動化生成多個路由
    • 由routers物件先註冊一個基本路由, 在配置過之後就會自動生成各種圍繞基本路由的路由了
    • 路由
from django.conf.urls import include
from django.urls import path,re_path
from api import views
from rest_framework import routers

router = routers.DefaultRouter()
# 兩個引數,一個是匹配的路由,一個是檢視中寫的CBV的類
router.register('book',views.BookView)

urlpatterns = [
    # re_path(r'^(?P<version>[v1|v2]+)/books/$', views.BookView.as_view()),
    # re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)$', views.BookDetailView.as_view()),
    # re_path(r'^(?P<version>[v1|v2]+)/book/$', views.BookView.as_view({'get':'list','post':'create'})),
    # re_path(r'^(?P<version>[v1|v2]+)/book/(?P<pk>\d+)/$', views.BookView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),

    re_path(r'^(?P<version>[v1|v2]+)/', include(router.urls)),
]
  • 檢視
from rest_framework.viewsets import ModelViewSet

class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

class BookView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializer
  • 我們輸入錯誤的路由,可以看到book生成了對應的4個路由

相關文章