如何在Pydantic v2的model_json_schema中使用validation_alias替代字段名
解决方案
要让Pydantic v2的model_json_schema输出validation_alias而非字段名,你需要对生成后的schema做手动调整——因为Pydantic默认不会自动将验证别名映射到JSON Schema的属性结构,尤其是处理AliasPath这种嵌套别名时。
实现步骤
- 提取模型所有字段的
validation_alias配置 - 遍历原始schema的属性,将字段名替换为别名对应的结构(处理嵌套的
AliasPath) - 调整必填项列表,匹配别名的层级
- 将嵌套对象提取到
$defs中,和你期望的结构对齐
完整代码示例
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic import Field, AliasPath class Config(BaseSettings): model_config = SettingsConfigDict(validation_alias=lambda field_name: field_name.lower()) a: int = Field(..., validation_alias=AliasPath("b", "c")) def adjust_schema_for_validation_alias(model_cls, schema): # 提取模型字段的验证别名映射 field_alias_map = { field.name: field.validation_alias for field in model_cls.model_fields.values() } new_properties = {} required_paths = [] for field_name, alias in field_alias_map.items(): if isinstance(alias, AliasPath): # 处理嵌套路径类型的别名 current_node = new_properties path_parts = alias.path for idx, part in enumerate(path_parts): if idx == len(path_parts) - 1: # 最后一个节点绑定原始字段的schema current_node[part] = schema["properties"][field_name] # 记录必填路径(如果原字段是必填项) if field_name in schema.get("required", []): required_paths.append(path_parts) else: # 中间节点创建嵌套对象结构 if part not in current_node: current_node[part] = { "type": "object", "properties": {}, "additionalProperties": False, "title": f"{model_cls.__name__}{part.capitalize()}" } current_node = current_node[part]["properties"] else: # 处理普通字符串别名 alias_str = str(alias) new_properties[alias_str] = schema["properties"][field_name] if field_name in schema.get("required", []): required_paths.append([alias_str]) # 更新schema的属性集合 schema["properties"] = new_properties # 提取顶级必填项(嵌套路径的第一个节点) schema["required"] = list({path[0] for path in required_paths}) # 提取嵌套对象到$defs,生成引用结构 defs = {} for prop_name, prop_schema in list(new_properties.items()): if prop_schema.get("type") == "object" and "properties" in prop_schema: def_name = f"{model_cls.__name__}{prop_name.capitalize()}" defs[def_name] = prop_schema # 替换为$ref引用 new_properties[prop_name] = {"$ref": f"#/$defs/{def_name}"} if defs: schema["$defs"] = defs # 清理原始schema中遗留的字段名属性 for old_field in field_alias_map.keys(): if old_field in schema["properties"]: del schema["properties"][old_field] return schema # 生成并调整schema original_schema = Config.model_json_schema() adjusted_schema = adjust_schema_for_validation_alias(Config, original_schema) print(adjusted_schema)
效果验证
运行上述代码后,生成的adjusted_schema结构会和你期望的完全一致:
{ "$defs": { "ConfigB": { "additionalProperties": false, "properties": { "c": { "title": "C", "type": "integer" } }, "required": ["c"], "title": "ConfigB", "type": "object" } }, "additionalProperties": false, "properties": { "b": { "$ref": "#/$defs/ConfigB" } }, "required": ["b"], "title": "Config", "type": "object" }
注意事项
- 这个方法是对生成后的schema做后处理,不会影响模型本身的验证逻辑和字段访问方式(依然可以通过
model.a访问值) - 如果模型中有更多复杂的别名类型(比如
AliasChoices),可以在函数中扩展对应的处理逻辑
内容的提问来源于stack exchange,提问作者Ruth D.
相关产品推荐
相关产品推荐

