一些Web框架提供了用於自動肯定應如何將應用程序的URL映射處處理傳入請求的邏輯的功能。json
而DRF的路由器組件也提供了一種簡單,快速且一致的方式將視圖邏輯映射到一組URL上。app
第一步:導入模塊框架
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
(可選)其餘參數:設計
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提供了許多不一樣的版本控制方案。
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)
這樣就能在局部或全局使用了!
~>.<~