现有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
相关产品推荐
相关产品推荐

