程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Django API 開發:視圖設置和路由

編輯:Python

前言

視圖集和路由器是 Django REST Framework 中的工具,可以加速 API 開發。 它們是視圖和 URL 之上的附加抽象層。 主要好處是單個視圖集可以替換多個相關視圖。 路由器可以自動為開發人員生成 URL。 在具有許多端點的大型項目中,這意味著開發人員必須編寫更少的代碼。 可以說,與一長串的單個視圖和 URL 相比,對於經驗豐富的開發人員而言,與少量視圖集和路由器組合相比,它更易於理解和推理。


在本章中,我們將向現有項目中添加兩個新的 API 端點,並了解如何從視圖和 URL 切換到視圖集和路由器可以用更少的代碼實現相同的功能。

用戶終端

當前,我們的項目中具有以下 API 端點。 它們都以 api/v1/ 開頭,為簡潔起見,未顯示它們:




前兩個端點是我們創建的,而django-rest-auth提供了另外五個端點。 現在讓我們添加兩個其他端點,以列出所有用戶和單個用戶。 這是許多 API 中的常見功能,它將使我們更清楚地理解為什麼將我們的視圖和 URL 重構為視圖集和路由器是有意義的。


傳統 Django 具有內置的 User 模型類,我們已經在上一篇文章中使用了該類進行身份驗證。 因此,我們不需要創建新的數據庫模型。 相反,我們只需要連接新的端點即可。 此過程始終涉及以下三個步驟:


  • 新增模型序列化器

  • 新增每個端點視圖

  • 新增每個端點的 URL 路由


從我們的序列化器開始。 我們需要導入 User 模型,然後創建一個使用它的 UserSerializer 類。 然後將其添加到我們現有的 posts/serializers.py文件中。


# posts/serializers.pyfrom django.contrib.auth import get_user_model # new from rest_framework import serializersfrom .models import Postclass PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = ('id', 'author', 'title', 'body', 'created_at',)class UserSerializer(serializers.ModelSerializer): # new class Meta: model = get_user_model() fields = ('id', 'username',)


值得注意的是,雖然我們在這裡使用 get_user_model 來引用 User 模型,但實際上在 Django 中有3種不同的方式來引用 User 模型。


通過使用 get_user_model ,我們確保我們引用的是正確的用戶模型,無論是默認用戶模型還是新 Django 項目中經常定義的自定義用戶模型。


接下來,我們需要為每個端點定義視圖。 首先將 UserSerializer 添加到導入列表中。 然後創建列出所有用戶的 UserList 類和提供單個用戶詳細視圖的 UserDetail 類。 就像我們的帖子視圖一樣,我們可以在此處使用 ListCreateAPIView 和 RetrieveUpdateDestroyAPIView。


對於每個端點,我們只需要只讀或GET功能。 這意味著我們可以使用 ListAPIView 和 RetrieveUpdateDestroyAPIView 。 我們還需要通過 get_user_model 引用用戶模型,以便將其導入第一行。


# posts/views.pyfrom django.contrib.auth import get_user_model # new from rest_framework import genericsfrom .models import Postfrom .permissions import IsAuthorOrReadOnlyfrom .serializers import PostSerializer, UserSerializer # newclass PostList(generics.ListCreateAPIView): 0 queryset = Post.objects.all() serializer_class = PostSerializer class PostDetail(generics.RetrieveUpdateDestroyAPIView): permission_classes = (IsAuthorOrReadOnly,) queryset = Post.objects.all() serializer_class = PostSerializer class UserList(generics.ListCreateAPIView): # new queryset = get_user_model().objects.all() serializer_class = UserSerializer class UserDetail(generics.RetrieveUpdateDestroyAPIView): # new queryset = get_user_model().objects.all() serializer_class = UserSerializer


如果您注意到,這裡有很多重復。 Post 視圖和 User 視圖都具有完全相同的 queryset 和 serializer_class。

最後,我們有了 URL 路由。 確保導入新的 UserList 和 UserDetail 視圖。 然後,我們可以為每個用戶使用前綴 users/


# posts/urls.pyfrom django.urls import pathfrom .views import UserList, UserDetail, PostList, PostDetail # newurlpatterns = [ path('users/', UserList.as_view()), # new path('users/<int:pk>/', UserDetail.as_view()), # new path('', PostList.as_view()), path('<int:pk>/', PostDetail.as_view()),]


我們完成了。 確保本地服務器仍在運行,並跳至可浏覽的 API 以確認一切正常。


我們的用戶列表端點位於 http://127.0.0.1:8000/api/v1/users/




狀態代碼為 200 OK ,表示一切正常。 我們可以看到三個現有用戶。


每個用戶的主鍵上都有一個用戶詳細信息終結點。 因此,我們的超級用戶帳戶位於:http://127.0.0.1:8000/api/v1/users/1/



視圖集

視圖集是一種將多個相關視圖的邏輯組合到單個類中的方法。 換句話說,一個視圖集可以替換多個視圖。 當前,我們有四個視圖:兩個用於博客帖子,兩個用於用戶。 相反,我們可以使用兩個視圖集來模仿相同的功能:一個用於博客文章,另一個用於用戶。


折衷方案是,對於不十分熟悉視圖集的其他開發人員,可讀性會有所下降。 所以這是一個權衡。當我們交換視圖集時,代碼在更新後的 posts/views.py 文件中是這樣的。


# posts/views.pyfrom django.contrib.auth import get_user_model from rest_framework import viewsets # newfrom .models import Postfrom .permissions import IsAuthorOrReadOnlyfrom .serializers import PostSerializer, UserSerializerclass PostViewSet(viewsets.ModelViewSet): # new permission_classes = (IsAuthorOrReadOnly,) queryset = Post.objects.all() serializer_class = PostSerializer class UserViewSet(viewsets.ModelViewSet): # new queryset = get_user_model().objects.all() serializer_class = UserSerializer


在頂部,而不是從 rest_framework 導入泛型,我們現在在第二行導入視圖集。 然後,我們使用ModelViewSet,它為我們提供了列表視圖和詳細信息視圖。 而且,我們不再需要像以前一樣為每個視圖重復相同的 queryset 和 serializer_class 。

Routers 路由

直接與視圖集一起使用,以自動為我們生成 URL 模式。 我們當前的 posts/urls.py 文件具有四個 URL模式:兩個用於博客文章,兩個用於用戶。相反,我們可以為每個視圖集采用一條路由。 因此,使用兩個路由而不是四個 URL 模式。 聽起來更好吧?


Django REST Framework 具有兩個默認路由器:SimpleRouter 和 DefaultRouter 。 我們將使用 SimpleRouter,但也可以為更多高級功能創建自定義路由器。


更新後的代碼如下所示:


# posts/urls.pyfrom django.urls import pathfrom rest_framework.routers import SimpleRouterfrom .views import UserViewSet, PostViewSetrouter = SimpleRouter()router.register('users', UserViewSet, base_name='users') router.register('', PostViewSet, base_name='posts')urlpatterns = router.urls


在最上面一行,將導入 SimpleRouter 及其視圖。 路由器設置為 SimpleRouter,我們為用戶和帖子“注冊”每個視圖集。 最後,我們將 URL 設置為使用新路由器。


繼續並立即檢查我們的四個端點! 用戶列表是相同的。




但是,局部視圖有些不同。 現在它被稱為“用戶實例”,而不是“用戶詳細信息”,並且還有一個附加的“刪除”選項內置於ModelViewSet中。




可以自定義視圖集,但是一個重要的折衷是用視圖集編寫更少的代碼,這是默認設置,它可能需要一些其他配置才能完全匹配您想要的內容。


轉到發布列表,我們可以看到它是相同的:




重要的是,我們的權限仍然有效。 使用我們的 testuser2 帳戶登錄時,Post Instance 為只讀。




但是,如果我們使用超級用戶帳戶(該日志是單獨的博客文章的作者)登錄的,那麼我們將具有完整的讀寫-編輯-刪除權限。



總結

視圖集和路由器是一種強大的抽象,可減少開發人員必須編寫的代碼量。 但是,這種簡潔性是以犧牲初始學習曲線為代價的。 最初幾次使用視圖集和路由器而不是視圖和 URL 模式會感到很奇怪。


最終,何時向項目添加視圖集和路由器的決定是相當主觀的。 一個好的經驗法則是從視圖和 URL 開始。 隨著 API 復雜性的增加,如果您發現自己一遍又一遍地重復相同的端點模式,那麼請查看視圖集和路由器。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved