绝大多数 laravel 和 drf 项目应将 api 版本号放在 url 路径中(如 /api/v1/users),因其调试直观、缓存友好、日志可读、nginx/cdn 路由可控;请求头方式虽更符合 rest 语义,但调试麻烦且代理可能丢弃自定义头。

API版本号该放在URL路径里还是请求头中
DRF默认支持多种版本控制方案,但URLPathVersioning和AcceptHeaderVersioning最常用。路径方式(如/api/v1/users/)对前端友好、调试直观、缓存可控;请求头方式(如Accept: application/json; version=1.0)更符合REST语义,但调试麻烦、CDN或代理可能丢弃自定义头。生产环境推荐路径方式——它不依赖客户端正确设置Accept头,也避免Nginx/Apache默认过滤Accept里的自定义参数。
配置示例:
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
'VERSION_PARAM': 'version',
}
注意:VERSION_PARAM仅在URLPathVersioning下影响URL匹配逻辑(比如设为'v'则匹配/api/v1/),但它不改变路由写法——你仍需在urls.py中显式写出v1或v2路径段。
如何让不同版本共用同一套视图类但行为不同
直接在视图方法里判断request.version是最轻量的做法,比维护两套视图更易维护。DRF把版本信息注入到request对象中,无需额外解析。
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
-
request.version是字符串(如'v1'),不是数字,比较时别用== 1 - 不要在
get_serializer_class()里硬编码if request.version == 'v2'就换类——应提取为独立方法,便于测试 - 字段级差异建议用
Serializer.to_representation()动态过滤,而非写两个序列化器
示例:
def list(self, request):
if request.version == 'v2':
# 返回带统计字段的数据
queryset = self.get_queryset().annotate(total_orders=Count('orders'))
else:
queryset = self.get_queryset()
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
为什么配置了URLPathVersioning却始终拿到默认版本
最常见原因是Django URL路由没把版本段作为命名组传给DRF。DRF的URLPathVersioning依赖正则捕获组version,必须显式命名且位置匹配。
- 错误写法:
path('api/v1/users/', UserListView.as_view())—— DRF无法从中提取version - 正确写法:
path('api/<version>/users/', UserListView.as_view())</version>,且确保version是URL pattern中的命名组名 - 如果用
re_path,必须写成re_path(r'^api/(?P<version>[a-zA-Z0-9]+)/users/$', ...)</version> - 检查
request.resolver_match是否包含version键,可快速定位路由是否传递成功
如何安全地废弃旧版API并引导用户迁移
单纯返回404或410不够友好。DRF不内置弃用提示,需手动加响应头和消息体。
- 在视图的
dispatch()或initial()中拦截已废弃版本,返回406 Not Acceptable比404更准确 - 添加
X-API-Deprecated: true和X-API-Deprecated-By: /api/v2/响应头,方便自动化工具识别 - 响应体中明确说明停用日期和替代路径,例如:
{"error": "v1 is deprecated as of 2025-03-01, use v2 instead"} - 切勿在
settings.py中通过ALLOWED_VERSIONS直接移除旧版——这会导致所有请求失败,应先灰度返回弃用提示
版本控制真正的难点不在配置,而在于跨版本数据兼容性:v1接口返回user_id,v2改叫id,前端可能直接炸掉。这类字段映射必须在序列化器层做透明转换,不能指望文档或提示。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










