路由器
一些Web框架提供了用于自动确定应如何将应用程序的URL映射到处理传入请求的逻辑的功能。
而DRF的路由器组件也提供了一种简单,快速且一致的方式将视图逻辑映射到一组URL上。
路由器组件的使用配合include
第一步:导入模块
from rest_framework import routers
第二步:实例化一个router对象
router = routers.SimpleRouter()
第三步:将需要自动生成url的接口注册到router中
router.register('books', views.BookView)
第四步:生成url
urlpatterns = [re_path('', include(router.urls)), ]
路由器简单的使用
from rest_framework import routersrouter = routers.SimpleRouter() router.register('books', BookView) router.register('users', UserView) urlpatterns = router.urls
register 方法有两个强制性参数:
- 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:
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.1Host: example.comAccept: 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 usesDjango'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.1Host: example.comAccept: 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 usesDjango's URL namespaces to determine the version.An example URL conf that is namespaced into two separate versions# users/urls.pyurlpatterns = [url(r'^/users/$', users_list, name='users-list'),url(r'^/users/(?P<pk>[0-9]+)/$', users_detail, name='users-detail')]# urls.pyurlpatterns = [url(r'^v1/', include('users.urls', namespace='v1')),url(r'^v2/', include('users.urls', namespace='v2'))]GET /1.0/something/ HTTP/1.1Host: example.comAccept: application/json"""pass# 将版本信息放在主机名里 Host class HostNameVersioning(BaseVersioning):"""GET /something/ HTTP/1.1Host: v1.example.comAccept: application/json"""pass# 将版本信息放在URL 查询参数里 class QueryParameterVersioning(BaseVersioning):"""GET /something/?version=0.1 HTTP/1.1Host: example.comAccept: 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 URLPathVersioningclass 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 BookSerializerVersion1return BookModelserializer
自定义
要实现自定义版本控制,请继承 BaseVersioning 并重写 determine_version 方法。
class MyVersion(versioning.BaseVersioning):def determine_version(self, request, *args, **kwargs):return request.META.get('version', None)
这样就能在局部或全局使用了!
~>.<~