zoukankan      html  css  js  c++  java
  • DRF Django REST framework 之 路由器与版本控制组件(七)

    路由器

    一些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 routers
    
    router = 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.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)

    这样就能在局部或全局使用了!

    ~>.<~

  • 相关阅读:
    e3.tree参考手册
    fckeditor使用详解
    提示constructor无法location的原因
    无限联动下拉框使用步骤
    动态sql构建的过程
    xsqlbuilder使用说明
    处理date类型对象的方式
    wdatepicker使用指南
    How to reclaim space in InnoDB when innodb_file_per_table is ON
    Bash script: report largest InnoDB files
  • 原文地址:https://www.cnblogs.com/pungchur/p/12043548.html
Copyright © 2011-2022 走看看