You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django Ninja Schema与TypedDict间转换?避免重复定义字段

Django Ninja Schema与TypedDict的字段复用及相互转换

问题背景

现有代码中需要同时定义TypedDict和Ninja Schema,存在字段重复冗余的问题:

from typing import TypedDict
from ninja import Schema

class MyDict(TypedDict):
  a: str

class MySchema(Schema):
  a: str

尝试通过class MySchema(Schema, MyDict): pass的多继承写法无法生成正确的Ninja Schema,同时需要实现两者的相互转换方案。


一、避免字段重复定义的方案

由于TypedDict和Ninja Schema的元类机制不同,直接多继承无法生效,可通过注解注入的方式复用字段:

方式1:直接在Schema类中注入注解

from typing import TypedDict
from ninja import Schema

class MyDict(TypedDict):
    a: str
    b: int

class MySchema(Schema):
    model_config = {"extra": "forbid"}  # 可选,限制仅允许定义的字段
    # 复用TypedDict的字段注解
    locals().update(MyDict.__annotations__)

方式2:封装工具函数批量转换

如果需要频繁转换,可封装工具函数实现TypedDict到Schema的动态生成:

def typed_dict_to_ninja_schema(typed_dict_cls):
    class DynamicSchema(Schema):
        model_config = {"extra": "forbid"}
    # 将TypedDict的字段注解复制到Schema
    DynamicSchema.__annotations__.update(typed_dict_cls.__annotations__)
    # 给动态类设置合理名称
    DynamicSchema.__name__ = f"{typed_dict_cls.__name__}Schema"
    return DynamicSchema

# 使用示例
MyDict = TypedDict("MyDict", {"a": str, "b": int})
MySchema = typed_dict_to_ninja_schema(MyDict)

二、Schema与TypedDict相互转换方案

1. Ninja Schema 转 TypedDict

提取Schema的字段注解,动态生成对应的TypedDict:

def ninja_schema_to_typed_dict(schema_cls):
    from typing import TypedDict
    # 过滤掉Schema内部的私有字段
    valid_annotations = {
        k: v for k, v in schema_cls.__annotations__.items()
        if not k.startswith('_')
    }
    return TypedDict(f"{schema_cls.__name__}TypedDict", valid_annotations)

# 使用示例
class MySchema(Schema):
    a: str
    b: int

MyDict = ninja_schema_to_typed_dict(MySchema)

2. TypedDict 转 Ninja Schema

复用前面的typed_dict_to_ninja_schema工具函数即可。


为什么多继承无效?

TypedDict的元类是TypedDictMeta,而Ninja Schema基于Pydantic,使用的是Pydantic的ModelMetaclass元类,两者的字段解析逻辑完全独立,多继承时无法将TypedDict的字段自动映射到Schema中,因此直接继承不生效。

内容的提问来源于stack exchange,提问作者Vulwsztyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:42:18