8.7 KiB
8.7 KiB
框架开发实施规范 (Django/DRF)
本规范专为基于 Django 与 Django REST Framework (DRF) 的后端项目制定。
执行策略:本规范采用“限制优先”原则。默认不提供多实现方案;未在本文明确允许的绕过做法,一律视为不合规。
工程配置与生态集成 (Settings & Ecosystem)
系统底座的配置与外部集成应当保持极度的干净、安全,并充分借力开源社区。
环境解耦与凭证安全
- 配置解耦:严禁将所有配置揉在单个 settings.py 中。必须使用多环境配置拆分(推荐 django-split-settings),严格划分通用配置、组件配置与环境独立配置。
- 凭证安全红线:密钥(如 SECRET_KEY, DB_PASSWORD, API Keys)必须从环境变量或配置中心动态读取,严禁在代码库中硬编码。
生态复用与外部集成
- 严禁重复造轮子:Django 和 DRF 拥有极其成熟的第三方开源生态。对于标准化的通用需求,必须优先集成成熟的第三方库。例如使用 djangorestframework-simplejwt 处理 Token,使用 django-filter 处理复杂查询过滤。
- 代理层无状态:若系统作为中间层代理外部 API(如大模型网关),代理视图禁止落库复杂的业务状态。
- 认证逻辑收口:对接外部系统的身份认证逻辑(如 LDAP、API Key)必须严格收拢在 DRF 的 Authentication 类或 Django 的中间件中,绝对禁止在业务 View 中直接读取 Request Headers 做条件分流。
- 认证冲突拒绝:当请求同时携带多种互斥认证凭证时,必须直接拒绝并返回统一错误,禁止按优先级做隐式降级兼容。
数据层规范 (Models & Serializers)
数据层负责实体定义与输入输出的格式化。清晰、防抖的数据层是系统性能的保障。
模型定义与约束
- 显式定义主键与审计:不推荐使用庞大的公共抽象基类隐式继承。业务 Model 应当显式定义主键和必备的审计字段(如 created_at, updated_at),避免基类变更带来全局副作用。
- 字段防空红线:字符型字段(CharField, TextField)禁止设置 null=True,必须设为 default=''。
- 外键明确声明:使用 ForeignKey 关联时必须显式指定清晰的 related_name。
- 枚举字段规范:枚举值优先使用 TextChoices 或 IntegerChoices,禁止散落硬编码字符串。
- 字段文档化:核心业务字段应补充 help_text,以保障文档可读性与维护一致性。
- 索引基线:高频过滤、排序与关联字段必须显式建索引,避免接口上线后暴露慢查询。
- 物理删除优先:默认优先使用物理删除。仅当业务明确要求审计追溯时引入逻辑删除(is_deleted)。若启用逻辑删除,必须配合使用带条件的唯一约束以防止重复插入冲突。
序列化层红线 (Serializers)
- 禁用全量暴露:严禁在 Serializer 中使用 fields = '__all__'。必须逐个显式列出对外暴露的字段,防止数据库新增敏感字段后发生意外泄露。
- 参数集中声明:字段级约束(如 read_only、required、write_only)优先通过 Meta.extra_kwargs 集中配置。
- 严防 N+1 查询:
- 列表接口严禁使用包含深层嵌套关系的复杂 Serializer,必须为其单独定义轻量级的结构。
- 若 Serializer 输出了外键字段,View 层的 QuerySet 必须配合使用 select_related 或 prefetch_related。
- 聚合计算隔离:严禁在 SerializerMethodField 中执行 SQL 聚合查询(如 .count(), .sum())。必须在 View 层使用 annotate() 提前计算完毕,Serializer 仅负责读取内存数据。
业务调度层规范 (Views, Services & URLs)
核心原则:Thin View, Fat Service (轻视图,重服务)。
View 层仅作为路由调度、参数校验和权限决策的枢纽,绝不可堆砌核心业务逻辑。
视图层职能划分
- 基类选型边界:标准 CRUD 强制使用 ModelViewSet;定制化业务场景强制选用 GenericViewSet 配合 Mixins 按需组合;APIView 仅限非标准资源形态(如透明代理)使用。
- 生命周期职责:
- get_queryset():必须在此处完成数据预加载与基于用户身份的数据范围隔离。
- get_serializer_class():必须实现读写分离(如基于 action 返回不同的 Serializer)。
- get_permissions():必须基于当前 action 动态分配权限类。
服务层下沉模式 (Service)
- 防腐红线:严禁重写 create(), update() 等主调度方法来堆砌业务逻辑(这会破坏 DRF 的标准执行流)。
- 标准移交:复杂的写操作逻辑,应当在 perform_create() 或 perform_update() 钩子中,提取并调用独立的 Service 函数/类 进行处理。
路由与异常处理
- 命名空间绝对隔离:全局强制采用 NamespaceVersioning 机制。根路由必须携带命名空间,且内部的 urls.py 必须存在 app_name。反向解析必须带版本号前缀。
- URL 风格统一:内部 REST 接口默认使用 kebab-case 与复数资源命名;第三方透传代理接口可按上游路径 1:1 保持。
- 异常抛出代替返回:遇到业务校验错误,严禁在代码中手动 return Response({"error": "xxx"})。必须直接抛出异常(如 raise ValidationError),交由全局的 exception_handler 统一格式化。
- 统一响应壳:严禁在 View 中手动构建类似 {"code": 0, "data": ...} 的字典,必须交由自定义的全局 Renderer 统一包装。
- 状态码语义化:HTTP 状态码必须通过
rest_framework.status常量引用,禁止直接写数字魔法值。
分页与文档规范
- 默认分页策略:常规列表接口默认使用 LimitOffsetPagination;仅在瀑布流、时间游标等场景使用 CursorPagination。
- 文档注解强制化:所有自定义 Action 与非标准接口必须显式补充
@extend_schema(至少包含 summary、description、request、responses)。 - 透传接口说明:代理第三方接口时,文档必须标注哪些字段为“上游原样透传”,避免接口语义歧义。
查询性能与异步基线
- N+1 防线:开发阶段必须启用 N+1 监测手段(插件或测试守卫),出现问题即阻断合并。
- 批量操作优先:批量写入与批量更新优先使用
bulk_create/bulk_update,禁止循环逐条写库。 - 大结果集迭代:处理大表时优先使用
iterator()或分批读取,避免一次性加载导致内存峰值过高。 - 异步边界清晰:异步视图仅用于高并发 I/O 场景,CPU 密集计算必须下沉到任务队列或独立计算服务。
- 耗时任务剥离:邮件、报表、第三方调用等明显耗时逻辑应通过异步任务框架执行,避免阻塞同步请求。
权限管控与数据隔离 (Permissions)
系统中的权限管控是防范越权访问、越权篡改的核心防线。必须绝对交由框架层(鉴权基类、过滤器)统一拦截。
功能权限 (操作级拦截)
- 禁用硬编码判断:绝对禁止在业务 Service 或 View 方法内部使用硬编码的 if 语句拦截权限(例如:if request.user.role != 'admin': raise PermissionDenied)。
- 规范抽象:功能权限必须抽象并继承 DRF 的 BasePermission,统一在 View 的 permission_classes 属性中进行声明与挂载。
对象级权限 (防越权篡改)
- 必须重写对象判定:对于针对单一资源的操作(如修改、删除),如果仅允许资源的拥有者或管理员操作,必须在权限类中实现 has_object_permission。
- 防跳过红线:DRF 仅在调用 self.get_object() 时才会触发对象级鉴权。在自定义 Action 中操作单个资源时,必须首先显式调用该方法获取对象,严禁直接使用 Model.objects.get(pk=pk) 从而绕过权限检查!
数据范围隔离 (防越权查看)
- 后端绝对阻断:绝对禁止依靠前端“不显示该列表”或“隐藏入口”来做数据隔离防护。
- 规范落实:不同租户(组织、用户)的数据隔离,必须通过重写 View 的 get_queryset() 进行彻底的 QuerySet 过滤来实现。
🤖 [附加] AI 助手执行协议 (AI Output Schema)
绝对红线:严格执行 Fat Service 模式。models.py 仅定义数据,services.py 处理所有核心业务逻辑,views.py 仅负责路由接客,绝对禁止在 View 中写复杂业务查询。