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

React/NextJS+Django技术栈如何实现前后端端到端类型安全?

React+TypeScript 前端 + Django 后端的前后端类型安全方案

针对你需要的跨前后端类型安全需求,以下是几种实用的实现方案,替代tRPC在该技术栈下的类型同步能力:

1. DRF + OpenAPI + TypeScript 类型生成

利用Django REST Framework的drf-spectacular插件生成标准OpenAPI Schema,再通过openapi-typescript工具将Schema转换为TypeScript类型,实现前后端类型严格对齐。

操作步骤:

  • 后端配置:
    安装drf-spectacular后,在settings.py中注册并配置:
    INSTALLED_APPS = [
        # 其他依赖
        'drf_spectacular',
    ]
    
    REST_FRAMEWORK = {
        'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
    }
    
    SPECTACULAR_SETTINGS = {
        'TITLE': '你的API名称',
        'VERSION': '1.0.0',
        'SERVE_INCLUDE_SCHEMA': False,
    }
    
    添加Schema路由到urls.py:
    from drf_spectacular.views import SpectacularAPIView
    
    urlpatterns = [
        # 其他路由
        path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
    ]
    
  • 前端生成类型:
    安装openapi-typescript,运行命令生成TS类型文件:
    npx openapi-typescript http://localhost:8000/api/schema/ --output src/types/api.ts
    
  • 前端使用:
    导入生成的类型,在请求时指定参数和响应类型:
    import type { paths } from '@/types/api';
    
    type UserDetailResponse = paths['/api/users/{id}']['get']['responses']['200']['content']['application/json'];
    
    async function fetchUser(userId: string): Promise<UserDetailResponse> {
      const res = await fetch(`/api/users/${userId}`);
      return res.json();
    }
    

2. Django Ninja + 类型化客户端生成

Django Ninja 基于Pydantic,天生支持Python类型注解,能自动生成OpenAPI Schema,搭配@hey-api/client工具可直接生成带类型的前端调用函数,体验接近tRPC的类型驱动开发。

操作步骤:

  • 后端定义API:
    安装django-ninja后,用Pydantic模型定义请求/响应类型:
    from ninja import NinjaAPI
    from pydantic import BaseModel
    from .models import User
    
    api = NinjaAPI()
    
    class UserOut(BaseModel):
        id: int
        username: str
        email: str
    
    @api.get('/users/{user_id}', response=UserOut)
    def get_user(request, user_id: int):
        user = User.objects.get(id=user_id)
        return {"id": user.id, "username": user.username, "email": user.email}
    
  • 前端生成类型化客户端:
    安装@hey-api/client,运行命令生成客户端代码:
    npx hey-api http://localhost:8000/api/docs/openapi.json --output src/api/client.ts
    
  • 前端使用:
    直接调用生成的类型化函数,自动获得参数和响应的类型提示:
    import { get_user } from '@/api/client';
    
    async function loadUser() {
      const user = await get_user({ user_id: 1 });
      // user 自动推导为 UserOut 对应的 TS 类型
    }
    

3. GraphQL + Graphene-Django + Codegen

通过GraphQL的强类型Schema实现前后端类型安全,用Graphene-Django在Django端定义GraphQL Schema,再用GraphQL Codegen生成TS类型和类型化查询函数。

操作步骤:

  • 后端配置:
    安装graphene-django后,定义GraphQL类型和查询:
    import graphene
    from graphene_django import DjangoObjectType
    from .models import User
    
    class UserType(DjangoObjectType):
        class Meta:
            model = User
            fields = ("id", "username", "email")
    
    class Query(graphene.ObjectType):
        user = graphene.Field(UserType, id=graphene.Int(required=True))
    
        def resolve_user(self, info, id):
            return User.objects.get(id=id)
    
    schema = graphene.Schema(query=Query)
    
  • 前端生成类型:
    安装@graphql-codegen/cli及相关插件,配置codegen.ts后运行生成:
    npx graphql-codegen
    
  • 前端使用:
    用生成的类型化查询函数调用API:
    import { useQuery } from '@apollo/client';
    import { GetUserDocument, GetUserQuery } from '@/generated/graphql';
    
    function UserProfile({ userId }: { userId: number }) {
      const { data } = useQuery<GetUserQuery>(GetUserDocument, {
        variables: { id: userId }
      });
      return <div>{data?.user?.username}</div>;
    }
    

4. 自定义类型同步脚本

如果需要高度定制,可编写Python脚本读取Django的Serializer或Pydantic模型,自动生成对应的TypeScript接口。示例脚本:

# generate_ts_types.py
from myapp.serializers import UserSerializer

def serializer_to_ts(serializer_cls):
    serializer = serializer_cls()
    ts_fields = []
    for name, field in serializer.fields.items():
        ts_type = "string"
        if hasattr(field, 'type') and field.type in ['integer', 'float']:
            ts_type = "number"
        elif field.type == 'boolean':
            ts_type = "boolean"
        ts_fields.append(f"  {name}: {ts_type};")
    return f"export interface {serializer_cls.__name__.replace('Serializer', '')} {{\n{chr(10).join(ts_fields)}\n}}"

with open("src/types/models.ts", "w") as f:
    f.write(serializer_to_ts(UserSerializer))

运行脚本即可生成TS类型,适合简单场景,但需要维护脚本适配不同字段类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 13:05:43