DRF Django REST framework 之 路由器與版本控制組件(七)

路由器

一些Web框架提供了用於自動肯定應如何將應用程序的URL映射處處理傳入請求的邏輯的功能。json

而DRF的路由器組件也提供了一種簡單,快速且一致的方式將視圖邏輯映射到一組URL上。app

路由器組件的使用配合include

第一步:導入模塊框架

from rest_framework import routers

第二步:實例化一個router對象post

router = routers.SimpleRouter()

第三步:將須要自動生成url的接口註冊到router中this

router.register('books', views.BookView)

第四步:生成urlurl

urlpatterns = [
    re_path('', include(router.urls)),
]

路由器簡單的使用

from rest_framework import routers

router = routers.SimpleRouter()
router.register('books', BookView)
router.register('users', UserView)
urlpatterns = router.urls

 register 方法有兩個強制性參數spa

  •  prefix    -   用於這組路由的URL前綴。
  •  viewset  -   視圖集類。

(可選)其餘參數:設計

  •  basename - 用於建立的URL名稱的基礎。若是未設置,則基名稱將基於queryset視圖集屬性自動生成(若是有)。
  • 請注意,若是視圖集不包含queryset屬性,則必須basename在註冊視圖時進行設置。

在使用路由組件以前的url:版本控制

urlpatterns = [

    path("books/", views.BookView.as_view({
        "get": "list",
        "post": "create",
    })),
    re_path('books/(?P<pk>\d+)/', views.BookView.as_view({
        'get': 'retrieve',
        'put': 'update',
        'delete': 'destroy'
    })),
]

使用路由器以後的url:rest

router = routers.DefaultRouter()
router.register("books", views.BookView)

urlpatterns = [
    re_path('', include(router.urls)),
]

能夠發現簡單了不少~

版本控制

API版本控制,能夠更改不一樣客戶端之間的行爲方式。REST框架提供了許多不一樣的版本控制方案例如:

某些客戶端 使用低版本只維護不開發新功能 v1

主要的產品還要不斷的更新迭代功能 v2

API 版本控制容許咱們在不一樣的客戶端之間更改行爲(同一個接口的不一樣版本會返回不一樣的數據)。 DRF提供了許多不一樣的版本控制方案。

DRF提供版本控制的五種方案

 rest_framework 框架裏的 versioning.py 文件

class BaseVersioning:
    pass


# 將版本信息放到請求頭中
class AcceptHeaderVersioning(BaseVersioning):
    """
    GET /something/ HTTP/1.1
    Host: example.com
    Accept: application/json; version=1.0 """
    pass


# 將版本信息放到URL中
class URLPathVersioning(BaseVersioning):
    """
    To the client this is the same style as `NamespaceVersioning`.
    The difference is in the backend - this implementation uses
    Django's URL keyword arguments to determine the version.

    An example URL conf for two views that accept two different versions.

    urlpatterns = [
        url(r'^(?P<version>[v1|v2]+)/users/$', users_list, name='users-list'),
        url(r'^(?P<version>[v1|v2]+)/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail')
    ]

    GET /1.0/something/ HTTP/1.1
    Host: example.com
    Accept: application/json
    """
    pass


# 將版本信息放在命名空間 namespace
class NamespaceVersioning(BaseVersioning):
    """
    To the client this is the same style as `URLPathVersioning`.
    The difference is in the backend - this implementation uses
    Django's URL namespaces to determine the version.

    An example URL conf that is namespaced into two separate versions

    # users/urls.py
    urlpatterns = [
        url(r'^/users/$', users_list, name='users-list'),
        url(r'^/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail')
    ]

    # urls.py
    urlpatterns = [
        url(r'^v1/', include('users.urls', namespace='v1')),
        url(r'^v2/', include('users.urls', namespace='v2'))
    ]

    GET /1.0/something/ HTTP/1.1
    Host: example.com
    Accept: application/json
    """
    pass


# 將版本信息放在主機名裏 Host
class HostNameVersioning(BaseVersioning):
    """
    GET /something/ HTTP/1.1
    Host: v1.example.com
    Accept: application/json
    """
    pass


# 將版本信息放在URL 查詢參數裏
class QueryParameterVersioning(BaseVersioning):
    """
    GET /something/?version=0.1 HTTP/1.1
    Host: example.com
    Accept: application/json
    """
    pass

版本控制的使用

以URL爲例:

設計 url :

router = routers.DefaultRouter()

router.register("books", views.BookView)

urlpatterns = [
    # 給url設置參數
    re_path('(?P<version>[v1|v2]+)/', include(router.urls)),
]

局部使用

導入模塊,使用就好了

from rest_framework.versioning import URLPathVersioning

class BookView(ModelViewSet):
    # 指定版本控制類,固定寫法
    versioning_class = URLPathVersioning
    # 獲取數據源, 固定寫法
    queryset = models.Book.objects.all()
    # 序列化類, 固定寫法
    serializer_class = BookSerializer

全局使用

以 URLPathVersioning 爲例,仍是在項目的 settings.py 中 REST_FRAMEWORK 配置項下配置:

REST_FRAMEWORK = {
    # 配置默認使用的版本控制類
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    # 默認的版本
    'DEFAULT_VERSION': 'v1',
    # 有效的版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    # 版本的參數名與URL conf中一致
    'VERSION_PARAM': 'version', 
}

這樣在視圖中就能夠經過訪問 request.version 來獲取當前請求的具體版本,而後根據不一樣的版原本返回不一樣的內容:

咱們能夠在視圖中自定義具體的行爲,下面以不一樣的版本返回不一樣的序列化類爲例:

class BookViewSet(ModelViewSet):
    # 獲取數據源,固定寫法
    queryset = models.Book.objects.all()
    # 指定序列化類,固定寫法
    serializer_class = BookModelserializer

    # 只要配置了版本,在視圖中就能經過 request.version 得到當前版本號
    def get_serializer_class(self):
        # 獲取當前序列化類的方法
        # 根據版本的不一樣返回不一樣的序列化類
        if self.request.version == 'v1':
            return BookSerializerVersion1
        return BookModelserializer

自定義

要實現自定義版本控制,請繼承 BaseVersioning 並重寫 determine_version 方法。

class MyVersion(versioning.BaseVersioning):
    def determine_version(self, request, *args, **kwargs):
        return request.META.get('version', None)

這樣就能在局部或全局使用了!

~>.<~

相關文章
相關標籤/搜索