ECC 实战指南:为 Django REST API 项目编写生产级 CLAUDE.md 技术规范
本文以 ECC 仓库中的真实示例文档 docs/ja-JP/examples/django-api-CLAUDE.md(英文原版见 examples/django-api-CLAUDE.md)为核心,讲解如何为基于 PostgreSQL 与 Celery 的 Django REST Framework 项目编写一份可直接落地的项目级
CLAUDE.md规范。读完本文,你将掌握一套覆盖编码规约、数据库与认证策略、目录结构、服务层与测试模式、环境变量、ECC 工作流集成的完整技术模板,并了解其背后的 ECC 命令与 Agent 源码支撑。
一、这份文档是什么:项目级 CLAUDE.md 的定位
在 ECC(The agent harness performance optimization system)体系中,CLAUDE.md 是放在项目根目录、供 Claude Code 等 Agent 读取的"项目宪法"。它把团队约定、技术选型、目录结构、关键模式、命令入口浓缩成 Agent 可直接遵循的规则,让 AI 助手在写代码、改代码、写测试时自动对齐团队标准,而不是每次都靠人肉灌输上下文。
文档开篇就明确了它的用法:
PostgreSQL 与 Celery を使用した Django REST Framework API の実世界サンプル。これをプロジェクトのルートにコピーしてサービスに合わせてカスタマイズしてください。 (这是一个基于 PostgreSQL 和 Celery 的 Django REST Framework API 的真实世界示例,请将它复制到项目根目录,并根据你的服务进行定制。)
也就是说,这是一份可复制、可定制的模板,而不是抽象说教。它完整定义了以下内容,本文后续将逐一展开:
- 技术栈与架构选型(Python 3.12+、Django 5.x、DRF、PostgreSQL、Celery + Redis、pytest、Docker Compose)
- 六大"关键规则"(Python 规约、数据库、认证、序列化器、错误处理、代码风格)
- 推荐的目录结构(
config/、apps/、core/三层) - 四个核心模式(服务层、视图模式、测试模式、环境变量)
- 测试策略与 ECC 工作流、Git 工作流
二、项目概览与架构约定
Stack: Python 3.12+, Django 5.x, Django REST Framework, PostgreSQL, Celery + Redis, pytest, Docker Compose
Architecture: 按业务领域拆分为独立 app 的领域驱动设计(DDD)。
API 层用 DRF,异步任务用 Celery,测试用 pytest。
所有端点只返回 JSON —— 不做模板渲染。
这段"架构宣言"有三个值得注意的决策:
- 全 JSON API:明确排除模板渲染,意味着项目是一个纯后端服务,前端(SPA / 移动端 / 第三方)通过 JSON 交互,这与 ECC 中
rules/与各语言评审 Agent 对"薄视图"的要求一致。 - 按业务领域拆分 app:
accounts(用户)、orders(订单)、products(商品)各自独立成 app,业务边界清晰,这也是 skills/django-patterns/SKILL.md 中推荐的 Django 工程结构。 - 异步任务走 Celery:耗时操作(如发送确认邮件)不阻塞请求线程,这正对应 agents/django-reviewer.md 中 HIGH 级别的性能红线——"视图中同步调用外部 API 会阻塞请求线程,应交给 Celery 异步处理"。
三、关键规则:一份可执行的编码契约
3.1 Python 规约
模板对 Python 代码提出了一套被 ruff/isort 强制执行的硬性规范:
- 所有函数签名必须带类型注解,使用
from __future__ import annotations; - 禁止
print()语句,统一使用logging.getLogger(__name__); - 字符串格式化只用 f-string,禁用
%与.format(); - 文件操作使用
pathlib.Path而非os.path; - 导入顺序按 isort 三组排列:标准库、第三方、本地(由 ruff 强制)。
这些约定并非空谈——在 ECC 的 commands/python-review.md 中,"使用 print 而不是 logging""未使用 f-string""魔法数字无命名常量"等均被列为 MEDIUM 级别审查项,说明模板中的每一条规则都有对应的自动化审查兜底。
3.2 数据库规则
- 所有查询使用 Django ORM,原生 SQL 仅允许
.raw()且必须参数化; - 迁移文件提交到 git,生产环境绝不使用
--fake; - 用
select_related()/prefetch_related()防止 N+1 查询; - 所有模型必须包含
created_at/updated_at自动字段; - 对出现在
filter()、order_by()或WHERE子句中的字段建立索引。
文档给出了最经典的 N+1 对比示例:
# 坏示例:N+1 查询
orders = Order.objects.all()
for order in orders:
print(order.customer.name) # 每个订单都命中一次数据库
# 好示例:JOIN 单查询
orders = Order.objects.select_related("customer").all()
这条规则在仓库源码中有更强的支撑:agents/django-reviewer.md 将"N+1 查询"列为 CRITICAL 级别(ORM 正确性),并给出了等价的坏/好示例;save() 不带 update_fields 覆盖整行写入、if queryset: 未用 .exists() 等也被列为 HIGH。也就是说,模板里的每一条数据库规则,都会被 django-reviewer 在实际代码评审中逐项核对。
3.3 认证规则
- 使用
djangorestframework-simplejwt实现 JWT——访问令牌 15 分钟、刷新令牌 7 天; - 每个视图都必须显式声明 permission 类,绝不依赖全局默认值;
- 以
IsAuthenticated为基底,对象级访问权限用自定义 permission 扩展; - 开启 token 黑名单(blacklist)以支持登出。
从 skills/django-security/SKILL.md 的视角看,这是典型的"最小权限 + 显式声明"安全模型;同时 agents/django-reviewer.md 将"DRF 视图缺少 permission_classes(默认落到全局配置)"列为 CRITICAL 安全项,与模板规则完全同构。
3.4 序列化器规则
- 简单 CRUD 用
ModelSerializer,复杂校验用Serializer; - 输入与输出形状不同时,拆分读写序列化器;
- 校验放在序列化器层,视图保持"薄"。
模板给出了读写序列化器分离的完整示例:
class CreateOrderSerializer(serializers.Serializer):
product_id = serializers.UUIDField()
quantity = serializers.IntegerField(min_value=1, max_value=100)
def validate_product_id(self, value):
if not Product.objects.filter(id=value, active=True).exists():
raise serializers.ValidationError("Product not found or inactive")
return value
class OrderDetailSerializer(serializers.ModelSerializer):
customer = CustomerSerializer(read_only=True)
product = ProductSerializer(read_only=True)
class Meta:
model = Order
fields = ["id", "customer", "product", "quantity", "total", "status", "created_at"]
注意几个可复用的细节:min_value/max_value 直接给出业务边界;字段级校验 validate_<field> 内联在序列化器里;读序列化器通过 read_only=True 嵌套关联对象,避免暴露内部 ID 结构。这与 skills/django-patterns/SKILL.md 中的 ProductCreateSerializer / ProductSerializer 分离模式如出一辙。
3.5 错误处理
- 使用 DRF 异常处理器统一错误响应格式;
- 业务异常定义在
core/exceptions.py; - 绝不向客户端暴露内部错误细节。
# core/exceptions.py
from rest_framework.exceptions import APIException
class InsufficientStockError(APIException):
status_code = 409
default_detail = "Insufficient stock for this order"
default_code = "insufficient_stock"
这个 InsufficientStockError 把 HTTP 409(Conflict)语义化,业务层 raise 即可,DRF 自动渲染成统一错误 JSON。后文的服务层示例会演示它如何与库存校验联动。
3.6 代码风格
- 代码与注释中不使用 emoji;
- 最大行宽 120 字符(ruff 强制);
- 类名 PascalCase、函数/变量 snake_case、常量 UPPER_SNAKE_CASE;
- 视图保持薄,业务逻辑放入服务函数或模型方法。
四、目录结构:DDD 的三层骨架
模板给出了完整的推荐目录树:
config/
settings/
base.py # 公共配置
local.py # 开发环境覆盖(DEBUG=True)
production.py # 生产配置
urls.py # 根路由
celery.py # Celery 应用配置
apps/
accounts/ # 用户认证、注册、资料
models.py
serializers.py
views.py
services.py # 业务逻辑
tests/
test_views.py
test_services.py
factories.py # Factory Boy 工厂
orders/ # 订单管理
models.py
serializers.py
views.py
services.py
tasks.py # Celery 任务
tests/
products/ # 商品目录
models.py
serializers.py
views.py
tests/
core/
exceptions.py # 自定义 API 异常
permissions.py # 共享权限类
pagination.py # 自定义分页
middleware.py # 请求日志、计时
tests/
这套结构有三层职责:
- config/ 采用拆分配置模式(split settings),与 skills/django-patterns/SKILL.md 推荐的
base.py / development.py / production.py / test.py拆分一致,local.py对应开发覆盖; - apps/ 每个业务域自包含 models、serializers、views、services、tests,
orders/tasks.py专门放 Celery 任务,实现了"业务逻辑进 service、异步任务进 tasks"的职责分离; - core/ 放跨 app 共享的异常、权限、分页、中间件,避免重复实现。
五、核心模式:服务层、视图与测试
5.1 服务层模式:事务、锁与异步解耦
# apps/orders/services.py
from django.db import transaction
def create_order(*, customer, product_id: uuid.UUID, quantity: int) -> Order:
"""带库存校验与支付暂扣地创建订单。"""
product = Product.objects.select_for_update().get(id=product_id)
if product.stock < quantity:
raise InsufficientStockError()
with transaction.atomic():
order = Order.objects.create(
customer=customer,
product=product,
quantity=quantity,
total=product.price * quantity,
)
product.stock -= quantity
product.save(update_fields=["stock", "updated_at"])
# 异步:发送确认邮件
send_order_confirmation.delay(order.id)
return order
这段代码浓缩了三个生产级要点:
select_for_update()行锁:先锁住商品行,再比较库存,防止并发下单导致超卖——这是典型的"检查-再操作"竞态防护;transaction.atomic()事务边界:订单创建 + 库存扣减要么全部成功、要么全部回滚,并且save(update_fields=[...])只更新变更字段,避免覆盖并发写入;.delay()异步解耦:发邮件不阻塞请求,交给 Celery worker。
对应到 ECC 的评审体系:agents/django-reviewer.md 将"多步写入缺少 transaction.atomic()""save() 不带 update_fields""业务逻辑放进视图/序列化器"分别列为 CRITICAL / HIGH / HIGH 项,模板中的服务层正是这些红线的最佳实践形态。
5.2 视图模式:薄视图 + 动态序列化器
# apps/orders/views.py
class OrderViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
pagination_class = StandardPagination
def get_serializer_class(self):
if self.action == "create":
return CreateOrderSerializer
return OrderDetailSerializer
def get_queryset(self):
return (
Order.objects
.filter(customer=self.request.user)
.select_related("product", "customer")
.order_by("-created_at")
)
def perform_create(self, serializer):
order = create_order(
customer=self.request.user,
product_id=serializer.validated_data["product_id"],
quantity=serializer.validated_data["quantity"],
)
serializer.instance = order
这个 ViewSet 完整展示了"薄视图"长什么样:
- 显式权限:
permission_classes = [IsAuthenticated],符合模板"绝不依赖默认权限"的规则; - 读写序列化器分离:
get_serializer_class()按 action 切换,创建用CreateOrderSerializer,其余用OrderDetailSerializer; - N+1 防护:
select_related("product", "customer")一次 JOIN 取出关联对象; - 用户上下文注入:在
perform_create里把self.request.user传入服务层,而不是在序列化器里偷偷访问request.user——这正是 agents/django-reviewer.md 强调的"注入用户上下文应在perform_create而非validate中"; - 分页:
pagination_class = StandardPagination对应 agents/django-reviewer.md 中"列表端点必须有分页,否则无界查询可能返回百万行"的 HIGH 检查。
5.3 测试模式:pytest + Factory Boy + APIClient
# apps/orders/tests/factories.py
import factory
from apps.accounts.tests.factories import UserFactory
from apps.products.tests.factories import ProductFactory
class OrderFactory(factory.django.DjangoModelFactory):
class Meta:
model = "orders.Order"
customer = factory.SubFactory(UserFactory)
product = factory.SubFactory(ProductFactory, stock=100)
quantity = 1
total = factory.LazyAttribute(lambda o: o.product.price * o.quantity)
# apps/orders/tests/test_views.py
import pytest
from rest_framework.test import APIClient
@pytest.mark.django_db
class TestCreateOrder:
def setup_method(self):
self.client = APIClient()
self.user = UserFactory()
self.client.force_authenticate(self.user)
def test_create_order_success(self):
product = ProductFactory(price=29_99, stock=10)
response = self.client.post("/api/orders/", {
"product_id": str(product.id),
"quantity": 2,
})
assert response.status_code == 201
assert response.data["total"] == 59_98
def test_create_order_insufficient_stock(self):
product = ProductFactory(stock=0)
response = self.client.post("/api/orders/", {
"product_id": str(product.id),
"quantity": 1,
})
assert response.status_code == 409
def test_create_order_unauthenticated(self):
self.client.force_authenticate(None)
response = self.client.post("/api/orders/", {})
assert response.status_code == 401
三个测试用例覆盖了三条关键路径:成功(201 + 金额计算正确)、业务失败(库存不足 → 409)、认证失败(未登录 → 401)。细节值得注意:
ProductFactory(price=29_99, stock=10)用下划线分隔符表达"29.99 元",total == 59_98精确验证金额计算;- 每个用例都断言具体状态码和返回数据,而不是只断言"请求不报错";
- 未认证用例调用
force_authenticate(None)显式清除认证。
这与 skills/django-tdd/SKILL.md 的 Red-Green-Refactor 流程(先写失败测试、再实现、再重构保持绿灯)、以及 pytest-django 的 --reuse-db、--nomigrations 等配置相呼应;agents/django-reviewer.md 也将"缺少 @pytest.mark.django_db""未使用 Factory 而直接用 Model.objects.create()""缺少权限边界测试"列为 MEDIUM 检查项,模板的测试模式恰好逐一规避。
六、环境变量:一套完整的 12-Factor 配置
# Django
SECRET_KEY=
DEBUG=False
ALLOWED_HOSTS=api.example.com
# 数据库
DATABASE_URL=postgres://user:pass@localhost:5432/myapp
# Redis(Celery broker + 缓存)
REDIS_URL=redis://localhost:6379/0
# JWT
JWT_ACCESS_TOKEN_LIFETIME=15 # 分钟
JWT_REFRESH_TOKEN_LIFETIME=10080 # 分钟(7 天)
# 邮件
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.example.com
每个变量都有明确用途与默认语义:
| 变量 | 含义 | 说明 |
|---|---|---|
SECRET_KEY |
Django 密钥 | 必须由环境注入,绝不硬编码(agents/django-reviewer.md 将硬编码 SECRET_KEY 列为 CRITICAL;skills/django-security/SKILL.md 要求缺失时直接 raise ImproperlyConfigured) |
DEBUG=False |
关闭调试 | 生产环境开启 DEBUG=True 会泄漏完整堆栈(CRITICAL) |
ALLOWED_HOSTS |
允许的 Host | 逗号分隔白名单 |
DATABASE_URL |
PostgreSQL 连接串 | 统一由配置层解析(如 dj-database-url) |
REDIS_URL |
Redis 连接 | 同时充当 Celery broker 与缓存后端 |
JWT_*_LIFETIME |
令牌有效期 | 访问 15 分钟、刷新 10080 分钟(7 天),单位为分钟 |
EMAIL_* |
邮件后端 | 生产用 SMTP,本地开发可换 console 后端 |
配置与运行环境说明:该模板面向 Python 3.12+、Django 5.x 与 PostgreSQL 的组合,JWT 有效期数值是模板建议值,落地时需根据自身安全策略调整。
七、测试策略:四种高频运行方式
# 运行全部测试
pytest --cov=apps --cov-report=term-missing
# 运行指定 app 的测试
pytest apps/orders/tests/ -v
# 并行执行
pytest -n auto
# 只跑上次失败的测试
pytest --lf
四种模式分别对应:全量回归 + 覆盖率报告、按 app 精准定位、并行加速(-n auto 依赖 pytest-xdist)、失败优先重跑(--lf 依赖 pytest 内置的 last-failed 插件)。如需强制覆盖率门槛,可结合 skills/django-tdd/SKILL.md 中的 pytest.ini 配置(如 --cov=apps、--cov-report=html、--reuse-db、--nomigrations)一起使用。
八、ECC 工作流:把 AI 助手接入 Django 开发生命周期
模板专门为使用 ECC 的团队列出了完整的命令工作流,这也是它与普通 Django 文档最大的不同:
# 计划
/plan "Add order refund system with Stripe integration"
# 用 TDD 开发
/tdd # 基于 pytest 的 TDD 工作流
# 评审
/python-review # Python 专属代码评审
/security-scan # Django 安全审计
/code-review # 通用质量检查
# 验证
/verify # 构建、lint、测试、安全扫描
这些命令在仓库中都有对应的真实实现,可以作为落地依据:
/plan(commands/plan.md):先复述需求、识别风险、拆解实施阶段,写任何代码前必须等待用户确认。适合"添加订单退款系统 + Stripe 集成"这类跨模块功能。/tdd:驱动 pytest 基础的 Red-Green-Refactor 循环,对应 skills/tdd-workflow/SKILL.md 与 skills/django-tdd/SKILL.md,要求 80%+ 覆盖率。/python-review(commands/python-review.md):执行ruff、mypy、pylint、black --check静态分析,并按 CRITICAL / HIGH / MEDIUM 三级输出报告;其中 CRITICAL 涵盖 SQL/命令注入、eval/exec、Pickle 反序列化、硬编码凭据等,HIGH 涵盖缺类型注解、可变默认参数、静默吞异常等。它背后调用 agents/python-reviewer.md Agent。/security-scan(commands/security-scan.md):对当前项目或指定路径运行 AgentShield 扫描(npx ecc-agentshield scan --path ... --format text),重点排查硬编码密钥、过宽权限、可执行 hooks、不受控的 MCP 服务器等,输出安全等级与按严重度分级的处置顺序,支持--min-severity过滤与--fix自动修复。/code-review:非 Python 专属的通用质量门禁,与python-review互补。/verify:一站式执行构建、lint、测试、安全扫描,作为合并前的最终闸门。
Django 专属评审 Agent
仓库中还有一位与本文档直接配套的专家:django-reviewer(agents/django-reviewer.md)。它的评审清单几乎就是本文档"关键规则"的可执行版本,例如:
- CRITICAL:SQL 注入、
DEBUG=True泄漏堆栈、硬编码SECRET_KEY、视图缺permission_classes、循环内 N+1、多步写入缺atomic()、模型变更缺迁移; - HIGH:序列化器
fields = '__all__'暴露敏感列、列表端点无分页、save()不带update_fields、视图中做业务逻辑、同步调用外部 API 阻塞请求线程; - MEDIUM:
print()代替 logging、缺related_name、缺__str__、测试用force_authenticate跳过认证逻辑。
它还会执行 python manage.py check、python manage.py makemigrations --check 等 Django 诊断命令,并输出 [SEVERITY] Issue / File / Fix 格式的评审报告,批准标准为:无 CRITICAL 与 HIGH 即 Approve,仅 MEDIUM 为 Warning,存在 CRITICAL/HIGH 则 Block。
九、Git 工作流与 CI/CD
模板最后定义了团队协作与发布纪律:
- 提交前缀约定:
feat:新功能、fix:缺陷修复、refactor:代码重构; - 从
main切出 feature 分支,合并必须走 PR; - CI 四件套:
ruff(lint + 格式化)、mypy(类型)、pytest(测试)、safety(依赖漏洞检查); - 部署:构建 Docker 镜像,通过 Kubernetes 或 Railway 托管。
这套 CI 组合与 commands/python-review.md 中列出的自动化检查(ruff check .、black --check .、isort --check-only .、bandit -r .、pip-audit、safety check、pytest --cov)高度一致,说明模板的 Git 规约是可被 CI 与 ECC 命令双重验证的,而非纸面约定。
十、如何将模板落地到自己的项目
- 复制模板:将 examples/django-api-CLAUDE.md(或日文版 docs/ja-JP/examples/django-api-CLAUDE.md)复制到项目根目录并重命名为
CLAUDE.md; - 裁剪与定制:按实际业务替换
accounts/orders/products示例 app,调整 JWT 有效期、环境变量名、测试目录与 CI 步骤; - 逐条对齐规则:让代码符合"关键规则"(类型注解、ORM-only、显式权限、读写序列化器分离、业务进 services.py);
- 接入 ECC 工作流:在团队中启用
/plan→/tdd→/python-review→/security-scan→/verify的完整循环,让 Agent 在每次改动时自动执行本文档中的规则; - 用 CI 兜底:将 ruff / mypy / pytest / safety 接入 CI,与
/verify形成人机双闸门。
对于使用 ECC 的 Django 团队,这份 CLAUDE.md 模板的真正价值在于:它把分散在 agents/django-reviewer.md、skills/django-patterns/SKILL.md、skills/django-security/SKILL.md、skills/django-tdd/SKILL.md 中的生产级经验,浓缩成一份 Agent 与人类工程师都能直接执行的单一事实来源——规则在前、模式居中、命令殿后,让 Django REST API 项目从一开始就跑在生产级轨道上。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.25 K640- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python780
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#561
Agent-Reach给你的 AI Agent 一键装上互联网能力。13 个平台(网页/GitHub/YouTube/小红书/B站/Twitter/Reddit 等)多后端路由,当下最稳的接入方式替你选好、装好、体检好。GitHub 主仓库同步镜像。Python1234
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go23045
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java37251