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

现有Django项目API版本化的最优目录结构咨询

Django应用API版本化实现方案(无侵入式)

针对你不能修改原有代码、需独立维护版本的需求,推荐采用在原有应用内创建版本子模块的结构,既能复用旧代码,又完全隔离新版本的修改,不会影响原有依赖。

推荐目录结构

project_dir
|___project_name_dir
    |___settings.py
    |___urls.py
    ...
|___app_1_dir
    |___ __init__.py
    |___ views.py       # 原有旧版本代码(默认作为v0版本)
    |___ serializers.py # 原有旧版本代码
    |___ models.py      # 模型统一复用,不做版本拆分
    |___ versions       # 版本化子模块根目录
        |___ __init__.py
        |___ v1         # 第一个新版本
            |___ __init__.py
            |___ views.py
            |___ serializers.py
            |___ urls.py
        |___ v2         # 后续新增版本同理
            |___ __init__.py
            |___ views.py
            |___ serializers.py
            |___ urls.py
    ...
|___app_2_dir
    ...

核心实现要点

1. 复用原有代码,仅修改差异部分

新版本的视图、序列化器直接继承原有根目录的类,只重写需要修改的逻辑,避免重复编码:

# app_1/versions/v1/serializers.py
from app_1.serializers import OldModelSerializer
from rest_framework import serializers

class V1ModelSerializer(OldModelSerializer):
    # 新增字段
    extra_field = serializers.CharField(required=False)
    
    class Meta(OldModelSerializer.Meta):
        # 继承旧字段并新增
        fields = OldModelSerializer.Meta.fields + ('extra_field',)

视图类同理,继承原有视图后修改特定方法:

# app_1/versions/v1/views.py
from app_1.views import OldModelViewSet
from .serializers import V1ModelSerializer

class V1ModelViewSet(OldModelViewSet):
    serializer_class = V1ModelSerializer
    
    # 仅重写需要修改的动作,比如list方法
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        # 对响应数据做自定义处理
        response.data['version'] = 'v1'
        return response

2. 路由隔离,新旧版本共存

在项目根urls.py中分别挂载旧版本和新版本的路由,确保原有API路径完全不变:

# project_name_dir/urls.py
from django.urls import path, include

urlpatterns = [
    # 旧版本路由(保持原样,兼容原有依赖)
    path('api/app1/', include('app_1.urls')),
    # 新版本路由,通过路径区分
    path('api/app1/v1/', include('app_1.versions.v1.urls')),
    path('api/app1/v2/', include('app_1.versions.v2.urls')),
]

每个版本的urls.py独立定义自身路由:

# app_1/versions/v1/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import V1ModelViewSet

router = DefaultRouter()
router.register(r'models', V1ModelViewSet)

urlpatterns = router.urls

3. 模型处理原则

模型不做版本拆分,因为数据库结构是全局共享的:

  • 如果需要新增字段,直接在原有模型上添加(设置null=True或合理默认值,不影响旧代码逻辑)
  • 如果需要大幅扩展模型逻辑,用OneToOneField关联新的扩展模型,新旧版本均可按需调用

4. 严格隔离修改

所有新增、修改的代码都放在versions子目录下,绝对不改动app_1根目录的任何文件,确保旧应用依赖的原有API完全不受影响。

方案优势

  • 无侵入式改造:完全保留原有代码结构,不会破坏现有依赖
  • 代码复用率高:新版本仅需编写差异逻辑,无需重复实现旧功能
  • 版本管理清晰:新增版本只需在versions下创建新目录,结构一目了然
  • 路由区分明确:新旧API路径完全分离,避免混淆

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 18:39:23