AcceptHeadersioning要求Accept头严格“media-type; version=xxx“格式,因为它只匹配分号后带空格的version参数;如果格式不一致,则requesttt.version为None,DEFAULT_需要配置VERSIONING_CLASS、DEFAULT_VERSION、ALLOWEDVERSIONS和VERSION_PARAM生效。
直接用 AcceptHeaderVersioning,但是,必须确保客户端请求头带 Accept: application/json; version=v1 这种格式,否则 request.version 会是 None 或触发 404。
AcceptHeaderVersioning 不分析任何键值对,只从 Accept 要求从头部提取 version=xxx 前提是整个头值符合这个子串 media-type; param=value 结构。常见错误包括:
- 发
Accept: v1→ 解析失败,request.version为None - 发
Accept: application/json, version=v1(逗号分隔)→ 不识别,跳过 - 发
Accept: application/json;v=v1(空格不足,参数名不正确)→ 匹配不上version键
正确的写法只有:Accept: application/json; version=v1 或 Accept: text/html; version=v2 —— 分号后必须有空格,分号后必须有空格 version= 是独立参数。
全局启用时,REST_FRAMEWORK 这些项目不能少:
立即学习“Python免费学习笔记(深入);
Python Django环境建设网站开发 WORD版
本文主要讲述Python Django环境建设网站开发;希望本文档能对有需要的朋友有所帮助;有兴趣的朋友可以来看看
下载'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning'-
'DEFAULT_VERSION': 'v1'(当请求头没有提供版本时 fallback 的值) -
'ALLOWED_VERSIONS': ['v1', 'v2'](必须明确声明,否则非默认版本将报告NotFound) -
'VERSION_PARAM': 'version'(虽然 header 模式不依赖 URL 但该配置仍被底层验证逻辑读取)
注意:VERSION_PARAM 在 header 该模型不用于分析,但它参与其中 is_allowed_version() 验证,漏配会导致合法版本被拒绝。
request.version 可能为 None(解析失败)、字符串(如 'v1')或 'v1' 非法价值以外(已通过) ALLOWED_VERSIONS 拦截)。实际判断建议:
- 不要直接写
if request.version == 'v1'—— 先确认不是None - 用
if request.version in ('v1', 'v2')更安全,避免拼写错误 - 序列化类切换示例:
def get_serializer_class(self): if self.request.version == 'v2': return Userserializerv2 return Userserializer
另外,request.versioning_scheme 是 AcceptHeaderVersioning 实例可用于反向生成兼容 header 的 URL(很少使用,但调试时可以检查 request.versioning_scheme.reverse(...))。
在视图 get() 开头加一行:
print(f"Accept header: {request.META.get('HTTP_ACCEPT')}")
print(f"Resolved version: {request.version}")然后用 curl 测试:curl -H "Accept: application/json; version=v2" http://localhost:8000/api/users/如果输出
Resolved version: v2 这是有道理的。如果还是这样的话。 None,90% 是 header 格式或空格问题。
真正容易被忽视的是:header 版本控制完全依赖于客户端的合作,服务端不能“强迫”客户端发送正确的头;一旦前端 SDK 或网关层重写 Accept,路由的整个版本失败了 —— 因此,建议将生产环境与日志监控相匹配 request.version is None 请求比例。