资讯动态

Django REST framework 3.4 发布详解:内置 Schema 生成、动态客户端与核心行为变更

发布时间:2026/9/19 3:03:26 来源:尧图企业网站定制
Django REST framework 3.4 发布详解内置 Schema 生成、动态客户端与核心行为变更【免费下载链接】django-rest-frameworkWeb APIs for Django. 项目地址: https://gitcode.com/gh_mirrors/dj/django-rest-framework3.4 是 Django REST frameworkDRF在「Schema 生成 → 超媒体支持 → API 客户端 → 实时支持」这一系列规划中的首个版本它首次把 API Schema 生成能力内置进框架核心并同步推出了命令行客户端与 Python 客户端库。读完本文你将掌握 DRF 3.4 的 Schema 生成机制Core API 与多格式渲染、generateschema命令与SchemaView动态 schema 的完整用法以及该版本中微秒精度时间输出、关系字段不再暴露 OPTIONS choices 等关键行为变更并了解如何通过自定义 metadata 类、encoder_class与AutoSchema子类对这些行为进行精细控制。一、3.4 发布背景与版本定位3.4 版本是 DRF 一系列计划的起点。按发布说明中的规划这一系列将依次解决schema 生成schema generation、超媒体支持hypermedia support、API 客户端API clients以及最终的实时支持realtime support四个方向的问题。3.4 正是第一步把 schema 生成能力正式纳入框架内置功能。该版本的开发由 Mozilla 开源支持MOSS项目资助 以及 DRF 的协作式资金模式共同推动。从仓库中保留的 Mozilla 资助公告 可以看到这笔资助的明确目标正是「支持无缝的客户端集成」框架提供 schema 或超媒体端点以暴露可用接口配套的 Python / JavaScript 客户端库与命令行客户端则动态地与之交互。3.4 的发布正是这一路线图中的首个落地成果。二、核心新特性内置 Schema 生成2.1 Core API格式无关的 Document Object ModelDRF 3.4 引入了基于Core API的 schema 生成支持。Core API 是一个用于描述 API 的Document Object Model文档对象模型它把 API schema 表示成与具体格式无关的内部结构。这套设计的巧妙之处在于由于Document对象是格式无关的框架可以让 renderer 类决定内部表示如何映射到外部 schema 格式从而把同一个Document渲染为多种不同的 schema 输出。这一机制也为此后自动生成 HTML 版 API 文档等能力打开了大门——只要把Document对象渲染成 HTML 文档页面即可。从当前仓库的 schemas 模块 结构可以印证这一演进路径模块内同时保留了面向 Core API 时代的generators.py顶层 schema 生成与inspectors.py逐端点视图自省以及后来 OpenAPI 时代的 openapi.py。仓库中的 schema 生成文档 已演进为基于 OpenAPI但 3.4 确立的「SchemaGenerator 遍历 URL 模式 renderer 决定输出格式」这一整体架构至今仍被沿用。2.2 支持的 schema 格式矩阵3.4 发布说明给出了当时对各类 schema 格式的支持情况格式名称支持程度PyPI 包Core JSONSchema 生成 客户端支持coreapi内置支持Swagger / OpenAPISchema 生成 客户端支持openapi-codec包JSON Hyper-Schema仅客户端支持hyperschema-codec包API Blueprint暂不可用暂不可用动态驱动的客户端能够以应用层接口而非网络层接口与 API 交互同时仍然保留 RESTful Web API 设计带来的好处——这是 3.4 引入客户端的核心价值主张。2.3 静态 Schema 生成generateschema管理命令如果你的 schema 是静态的可以使用generateschema管理命令离线生成。当前仓库中该命令的实现位于 rest_framework/management/commands/generateschema.py从源码可见它支持以下参数./manage.py generateschema \ --title Your API \ --description API description \ --api_version 1.0.0 \ --url https://example.org/api/ \ --format openapi \ --file openapi-schema.yml命令行参数说明对应 generateschema.py--titleAPI 名称默认空字符串--urlAPI 根 URL--descriptionAPI 描述文本--format输出格式可选openapiYAML默认或openapi-json--urlconf指定用于生成 schema 的 URL conf 模块名默认取settings.ROOT_URLCONF--generator_class指定自定义的SchemaGenerator子类以import_string方式加载--file输出文件路径不指定时输出到 stdout--api_versionAPI 版本号。从源码的handle()方法可以看到完整调用链实例化SchemaGenerator→ 调用generator.get_schema(requestNone, publicTrue)→ 根据--format选择OpenAPIRendererYAML或JSONOpenAPIRendererJSON渲染。需要说明的是命令在 3.4 时代输出的是 Core API 渲染结果当前仓库版本已演进为 OpenAPI 输出但「命令离线生成 renderer 决定格式」的设计思路一脉相承。生成 schema 后你可以补充任何无法被生成器自动推断的附加信息也可以把 schema 纳入版本控制、随每个新版本更新或作为站点静态资源对外提供。2.4 动态 Schema 生成SchemaView与get_schema_view()当 schema 依赖数据库运行时值例如外键 choices 取决于数据库内容时需要动态 schema。此时可以通过get_schema_view()辅助函数挂载一个SchemaView按需生成并对外提供 schema。在urls.py中from rest_framework.schemas import get_schema_view urlpatterns [ # ... # title 和 description 参数会传递给 SchemaGenerator。 # 提供视图名称以便 reverse() 使用。 path( openapi, get_schema_view( titleYour Project, descriptionAPI for all things …, version1.0.0 ), nameopenapi-schema, ), # ... ]get_schema_view()支持的关键字参数见 rest_framework/schemas/init.py参数说明titleschema 定义的描述性标题description更长的描述文本versionAPI 版本号urlschema 的规范基础 URL例如urlhttps://www.example.org/api/urlconf生成 schema 所用的 URL conf 导入路径字符串默认取 Django 的ROOT_URLCONFpatterns限制 schema 自省范围的 URL 模式列表例如只想暴露myproject.api时传入[path(api/, include(myproject.api.urls))]public是否绕过视图权限生成 schema默认Falsegenerator_class传入SchemaView的自定义SchemaGenerator子类authentication_classesschema 端点适用的认证类列表默认DEFAULT_AUTHENTICATION_CLASSESpermission_classesschema 端点适用的权限类列表默认DEFAULT_PERMISSION_CLASSESrenderer_classes渲染 API root 端点可用的 renderer 类集合2.5 顶层定制SchemaGeneratorSchemaGenerator负责遍历配置的 URL 模式、为每个视图请求 schema 并汇总成最终结果。你通常不需要自己实例化它但可以这样做from rest_framework.schemas.openapi import SchemaGenerator generator SchemaGenerator(titleStock Prices API)其构造参数包括title必填API 名称、description描述文本、version默认0.1.0、urlAPI schema 根 URLschema 位于路径前缀下时需要、patterns待检查的 URL 列表默认取项目 URL conf、urlconfURL conf 模块名默认settings.ROOT_URLCONF。get_schema(requestNone, publicFalse)返回表示 schema 的字典request参数可选用于按用户权限过滤 schema 生成结果。这是定制顶层 schema 的理想覆写点例如为顶层info对象添加服务条款class TOSSchemaGenerator(SchemaGenerator): def get_schema(self, *args, **kwargs): schema super().get_schema(*args, **kwargs) schema[info][termsOfService] https://example.com/tos.html return schema自定义子类可通过generateschema命令的--generator_class或get_schema_view(generator_class...)注入。2.6 逐视图定制AutoSchema默认情况下视图自省由APIView上schema属性指向的AutoSchema实例完成auto_schema some_view.schema。它为每个视图、请求方法与路径提供两类 OpenAPI 元素OpenAPI components在 DRF 语境下即描述请求/响应体的 serializer 映射OpenAPI operation object描述端点包括分页、过滤等路径与查询参数。SchemaGenerator在编译 schema 时会对每个视图、允许的方法与路径调用get_components()和get_operation()。需要特别注意自动自省组件与多数 operation 参数依赖GenericAPIView的get_serializer()、pagination_class、filter_backends等属性与方法。对基础APIView子类而言默认自省基本仅限于 URL kwarg 路径参数。AutoSchema的设计原则是把 schema 生成逻辑集中在一处而不是散布在视图、serializer 与 field API 中。自定义时也应保持这一封装不要通过在视图上挂schema_extra_info之类属性让 schema 逻辑「泄漏」到视图层而应通过AutoSchema子类或__init__()kwargs 承载额外信息例如class BaseSchema(AutoSchema): 知道如何使用 extra_info 的 AutoSchema 子类。 ... class CustomSchema(BaseSchema): extra_info ... # 一些额外信息 class CustomView(APIView): schema CustomSchema()当某个选项需要被多个视图类共用时可在基类AutoSchema子类的__init__()中以 kwarg 方式接收避免为每个视图单独创建子类class CustomSchema(BaseSchema): def __init__(self, **kwargs): # 保存 extra_info 供后续使用 self.extra_info kwargs.pop(extra_info) super().__init__(**kwargs) class CustomView(APIView): schema CustomSchema(extra_info...) # 一些额外信息AutoSchema的常用__init__()kwargs 包括tags手动指定标签列表、component_name指定组件名、operation_id_base指定 operation ID 的资源名部分在视图上声明即可class PetDetailView(generics.RetrieveUpdateDestroyAPIView): schema AutoSchema( tags[Pets], component_namePet, operation_id_basePet, ) ...当多个视图指向同一模型、或存在同名 serializer 导致组件名/operationId 重复时这些 kwargs 通常就是解决方案。此外AutoSchema还提供了可覆写的核心方法get_components()生成描述请求/响应体的组件默认返回单对映射可覆写返回多对get_component_name()根据 serializer 计算组件名get_reference()返回 serializer 组件的引用map_serializer()将 serializer 映射为 OpenAPI 表示map_field()将单个 serializer 字段映射为 schema 表示对于 schema 无法确定的SerializerMethodField或自定义字段子类应覆写此方法第三方包作者也应提供AutoSchema子类与 mixin 覆写map_field()方便用户为自定义字段生成 schemaget_tags()按路由 URL 首段分组如/users/{id}/生成标签usersget_operation()返回描述端点的 OpenAPI operation 对象get_operation_id()生成唯一 operationId默认从模型名、serializer 名或视图名推导呈 camelCase如listItems、retrieveItem、updateItemget_operation_id_base()多个视图使用同一模型名导致 operationId 重复时覆写此方法提供不同的名称基座get_serializer()/get_request_serializer()/get_response_serializer()返回视图 serializer后两者默认返回get_serializer()的结果可分别覆写以区分请求与响应对象。三、配套的 API 客户端生态3.4 在内置 schema 支持之外还同步提供了两个配套工具命令行客户端command line client用于与 API 交互的命令行工具Python 客户端库Python client library用于与 API 交互的 Python 库。这两个客户端都是动态驱动的能够与任何暴露受支持 schema 格式的 API 交互——也就是说客户端并不与 DRF 强绑定其他实现 Core API 或受支持 schema 格式的服务同样可以被这些客户端调用。发布说明同时预期在后续数月内扩展客户端库所支持的语言范围并计划继续完善 schema 支持的成熟度包括文件上传/下载的文档支持、文档生成与参数注解的改进。此外发布说明还提到 Django REST Swagger 包正在筹备与内置支持对接的 2.0 版本体现了 3.4 schema 能力对第三方生态的直接带动作用。四、支持的版本矩阵3.4.0 新增了对 Django 1.10 的支持。该版本支持的 Python 与 Django 版本为Django1.8、1.9、1.10Python2.7、3.2(*)、3.3(*)、3.4、3.5。(*) 注意从 Django 1.9 起不再支持 Python 3.2 与 3.3。五、弃用与行为变更3.4 的弃用与行为变更非常有限升级路径相当直接。但其中三项变更值得逐一说明因为它们直接影响序列化输出、API 元数据暴露与 OPTIONS 请求的行为。5.1 serializer 类必须使用 fields 或 exclude3.3.0 中从「待弃用pending deprecation」升级为「已弃用deprecated」的变更ModelSerializer与HyperlinkedModelSerializer应包含fields或exclude选项。已弃用的用法仍然可用但会触发警告。fields __all__快捷写法可用于显式包含全部字段。该项要求至今仍是 DRF 序列化器声明的规范写法。5.2 时间与日期时间输出改为微秒精度默认 JSON renderer 在直接返回datetime或time实例时精度由原来的毫秒3 位改为微秒6 位使输出格式与serializers.DateTimeField、serializers.TimeField的默认字符串输出保持一致。这一变更不影响使用 serializer 时的默认行为——通过 serializer 序列化时datetime与time实例本来就以微秒精度输出字符串。两类行为可以分别调整serializer 行为通过DATETIME_FORMAT与TIME_FORMAT设置修改renderer 行为在JSONRenderer子类上设置自定义encoder_class属性修改。从当前仓库源码看JSONRenderer 通过类属性encoder_class encoders.JSONEncoder暴露编码器而 utils/encoders.py 中的JSONEncoder对datetime.datetime与datetime.time均调用obj.isoformat()生成字符串——isoformat()在存在微秒时会输出 6 位小数这正是微秒精度输出的底层来源。因此自定义编码器只需继承JSONEncoder并覆写default()再赋给自定义 renderer 的encoder_class即可改变输出格式。5.3 OPTIONS 请求不再返回关系字段的 choices对包含 serializer choices 字段的视图发起OPTIONS请求时响应中会返回可用 choices 列表。此前的行为是对于关系字段relational field会返回可选择的实例列表。为最小化信息暴露新行为改为不返回关系字段的 choices 信息。若要覆盖此行为需要实现自定义 metadata 类。从当前仓库的 rest_framework/metadata.py 可以看到get_field_info()的取值逻辑choices仅在字段具有choices属性hasattr(field, choices)时才被收集——这正是 3.4 变更的源码级体现关系字段如PrimaryKeyRelatedField不再携带choices因此自然被排除在 OPTIONS 响应之外。相关的行为细节可参考 GitHub 上的 issue #3751。六、自描述 API 与 schema 的可视化效果DRF 的 schema 能力与可浏览 APIbrowsable API共同构成了「自描述 API」体验每个 API 端点的文档可以直接通过浏览器访问该 URL 获得。如上图所示可浏览 API 页面不仅展示端点说明与认证信息还直接呈现GET /snippets/的请求方法、HTTP 200 OK响应状态、响应头Allow: HEAD, OPTIONS, POST, GET以及分页后的 JSON 响应体。这一自描述能力与 3.4 引入的 schema 生成相辅相成让 API 的发现、文档化与客户端接入变得更加顺畅。七、升级与后续资源3.4 的完整分项发布说明收录于仓库的 release notes同时该版本汇集了数量庞大的 pull request 与 issue 贡献。围绕新功能可以继续阅读以下仓库内资料Schema 生成 API 指南完整的SchemaGenerator、AutoSchema、generateschema命令与SchemaView用法Metadata API 指南了解 OPTIONS 行为与自定义 metadata 类Mozilla 资助公告3.4 开发路线图与客户端库计划的背景Documenting your APIAPI 文档化方案与自描述 API 的完整介绍。对绝大多数项目而言从 3.3 升级到 3.4 几乎无需改动代码——只需按上述三项行为变更核对序列化器声明、时间输出格式与 OPTIONS 元数据暴露即可平滑过渡。【免费下载链接】django-rest-frameworkWeb APIs for Django. 项目地址: https://gitcode.com/gh_mirrors/dj/django-rest-framework创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价