django-clean-drf

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Django Clean DRF Architect

Django Clean DRF 架构指南

Overview

概述

This skill provides expert guidance for creating Django REST Framework applications following Clean Architecture principles. It enforces a strict layered architecture that separates concerns, maximizes testability, and produces maintainable production-quality code.
Architecture Layers:
HTTP Layer (Views/Serializers)
Application Layer (Use Cases + DTOs)
Domain Layer (Services + Models)
Infrastructure Layer (ORM, External APIs, Cache)
Key Capabilities:
  • Layered architecture with strict dependency rules (dependencies flow inward only)
  • Use Case pattern with dataclass Input/Output DTOs
  • Service layer for domain logic (static queries, instance mutations)
  • Thin views that delegate to use cases
  • Separate Read vs Create/Update serializers
  • Explicit error handling without exceptions for business logic
  • Modern Python 3.12+ and Django 5+ features
  • Full type hints and testability by design
本Skill提供遵循Clean Architecture原则创建Django REST Framework应用的专业指导。它采用严格的分层架构实现关注点分离,最大化可测试性,并生成可维护的生产级代码。
架构分层:
HTTP Layer (Views/Serializers)
Application Layer (Use Cases + DTOs)
Domain Layer (Services + Models)
Infrastructure Layer (ORM, External APIs, Cache)
核心能力:
  • 遵循严格依赖规则的分层架构(依赖仅向内流动)
  • 结合数据类Input/Output DTO的用例模式
  • 承载领域逻辑的服务层(静态查询、实例变更)
  • 仅负责委托的轻量视图
  • 读写分离的序列化器
  • 业务逻辑无异常的显式错误处理
  • 适配Python 3.12+和Django 5+的现代特性
  • 原生支持类型提示,设计即保证可测试性

When to Use

适用场景

Invoke this skill when you encounter these triggers:
New Application Setup:
  • "Create a new Django API for..."
  • "Start a new DRF project with clean architecture"
  • "Set up a new app with layered architecture"
  • "Initialize a domain-driven Django application"
  • "Scaffold a Django app following SOLID"
Use Case Implementation:
  • "Create a use case for..."
  • "Implement the business logic for..."
  • "Add a new operation/action for..."
  • "Handle this transaction atomically"
Service Layer:
  • "Create a service for..."
  • "Where should this business logic go?"
  • "Implement domain validation for..."
  • "Query data following clean architecture"
Architecture Questions:
  • "How do I structure this Django app?"
  • "What layer should handle..."
  • "How do I avoid fat views/models?"
  • "How do I make this testable?"
  • "Apply SOLID principles to Django"
API Design:
  • "Create API endpoints for..."
  • "Design the serializers for..."
  • "Implement CRUD for this entity"
当遇到以下场景时,可调用本Skill:
新应用搭建:
  • "为...创建新的Django API"
  • "采用整洁架构启动新的DRF项目"
  • "搭建采用分层架构的新应用"
  • "初始化领域驱动的Django应用"
  • "遵循SOLID原则搭建Django应用脚手架"
用例实现:
  • "为...创建用例"
  • "实现...的业务逻辑"
  • "为...添加新操作/动作"
  • "原子化处理该事务"
服务层开发:
  • "为...创建服务"
  • "该业务逻辑应该放在哪里?"
  • "实现...的领域验证"
  • "遵循整洁架构查询数据"
架构相关问题:
  • "如何规划这个Django应用的结构?"
  • "...应该由哪一层负责?"
  • "如何避免臃肿的视图/模型?"
  • "如何让代码具备可测试性?"
  • "在Django中应用SOLID原则"
API设计:
  • "为...创建API端点"
  • "设计...的序列化器"
  • "为该实体实现CRUD操作"

Instructions

操作流程

Follow this workflow when handling Django Clean DRF requests:
处理Django Clean DRF相关请求时,请遵循以下流程:

1. Analyze Requirements and Establish Context

1. 分析需求并确立上下文

Understand the domain:
  • What entities/models are involved?
  • What operations/actions are needed?
  • What business rules must be enforced?
  • Are there external dependencies (APIs, queues)?
Check existing project structure:
  • Review existing apps and their organization
  • Identify patterns already in use
  • Check Django/Python versions for feature availability
Determine scope:
  • Single use case or full CRUD?
  • New app or extending existing?
  • API-only or includes admin?
理解业务领域:
  • 涉及哪些实体/模型?
  • 需要实现哪些操作/动作?
  • 必须遵循哪些业务规则?
  • 是否存在外部依赖(API、队列等)?
检查现有项目结构:
  • 回顾现有应用及其组织方式
  • 识别已在使用的开发模式
  • 检查Django/Python版本以确认可用特性
确定范围:
  • 单个用例还是完整CRUD?
  • 新应用还是扩展现有应用?
  • 仅API还是包含Admin后台?

2. Load Relevant Reference Documentation

2. 加载相关参考文档

Based on the task, reference the appropriate bundled documentation:
Architecture:
  • New app setup
    references/project-structure.md
  • Use case implementation
    references/use-cases-pattern.md
  • Service layer
    references/services-pattern.md
  • Models and domain logic
    references/models-domain.md
  • Views and serializers
    references/views-serializers.md
  • Testing
    references/testing-clean-arch.md
  • Complete examples
    references/examples.md
API Development:
  • Query optimization / N+1
    references/query-optimization.md
  • Pagination, filtering, search
    references/api-patterns.md
  • Authentication / JWT / Permissions
    references/authentication.md
  • Production deployment
    references/production-api.md
  • Django Admin for APIs
    references/django-admin.md
Code Quality:
  • Coding standards / Ruff / Security
    references/coding-standards.md
根据任务需求,参考对应的内置文档:
架构相关:
  • 新应用搭建
    references/project-structure.md
  • 用例实现
    references/use-cases-pattern.md
  • 服务层
    references/services-pattern.md
  • 模型与领域逻辑
    references/models-domain.md
  • 视图与序列化器
    references/views-serializers.md
  • 测试
    references/testing-clean-arch.md
  • 完整示例
    references/examples.md
API开发:
  • 查询优化 / N+1问题
    references/query-optimization.md
  • 分页、过滤、搜索
    references/api-patterns.md
  • 认证 / JWT / 权限控制
    references/authentication.md
  • 生产环境部署
    references/production-api.md
  • Django Admin适配API
    references/django-admin.md
代码质量:
  • 编码规范 / Ruff / 安全
    references/coding-standards.md

3. Implement Following Clean Architecture Principles

3. 遵循Clean Architecture原则实现

CRITICAL: Layer Dependency Rules
Views → Use Cases → Services → Models
  ↓         ↓           ↓         ↓
Serializers  DTOs    (internal)   ORM
  • Dependencies flow INWARD only (outer layers depend on inner)
  • Never import views in use cases, or use cases in services
Use Case Pattern:
python
from dataclasses import dataclass
from uuid import UUID
from django.db import transaction

@dataclass(frozen=True, slots=True)
class CreateOrderInput:
    customer_id: UUID
    items: list['OrderItemInput']
    notes: str | None = None

@dataclass(frozen=True, slots=True)
class CreateOrderOutput:
    success: bool
    order_id: UUID | None = None
    error: str | None = None

class CreateOrderUseCase:
    def __init__(
        self,
        order_service: OrderService,
        inventory_service: InventoryService,
    ):
        self._order_service = order_service
        self._inventory_service = inventory_service

    @transaction.atomic
    def execute(self, input_dto: CreateOrderInput) -> CreateOrderOutput:
        # Validate
        is_valid, error = self._inventory_service.validate_availability(input_dto.items)
        if not is_valid:
            return CreateOrderOutput(success=False, error=error)

        # Execute
        order = self._order_service.create(
            customer_id=input_dto.customer_id,
            items=input_dto.items,
        )
        return CreateOrderOutput(success=True, order_id=order.id)
Service Pattern:
python
class OrderService:
    # STATIC methods for QUERIES (no state changes)
    @staticmethod
    def get_by_id(order_id: UUID) -> Order | None:
        return Order.objects.select_related('customer').filter(id=order_id).first()

    # INSTANCE methods for MUTATIONS (state changes)
    def create(self, customer_id: UUID, items: list[OrderItemInput]) -> Order:
        order = Order.objects.create(customer_id=customer_id)
        for item in items:
            OrderItem.objects.create(order=order, **item.__dict__)
        return order

    # VALIDATION returns tuple[bool, str]
    def validate_can_cancel(self, order: Order) -> tuple[bool, str]:
        if order.status == Order.Status.SHIPPED:
            return False, "Cannot cancel shipped orders"
        return True, ""
Thin View Pattern:
python
class CreateOrderView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request: Request) -> Response:
        serializer = CreateOrderSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        use_case = CreateOrderUseCase(
            order_service=OrderService(),
            inventory_service=InventoryService(),
        )
        input_dto = CreateOrderInput(**serializer.validated_data)
        output = use_case.execute(input_dto)

        if not output.success:
            return Response({'error': output.error}, status=400)
        return Response({'order_id': str(output.order_id)}, status=201)
Serializer Separation:
python
undefined
核心要求:分层依赖规则
Views → Use Cases → Services → Models
  ↓         ↓           ↓         ↓
Serializers  DTOs    (internal)   ORM
  • 依赖仅向内流动(外层依赖内层)
  • 禁止在用例中导入视图,或在服务中导入用例
用例模式:
python
from dataclasses import dataclass
from uuid import UUID
from django.db import transaction

@dataclass(frozen=True, slots=True)
class CreateOrderInput:
    customer_id: UUID
    items: list['OrderItemInput']
    notes: str | None = None

@dataclass(frozen=True, slots=True)
class CreateOrderOutput:
    success: bool
    order_id: UUID | None = None
    error: str | None = None

class CreateOrderUseCase:
    def __init__(
        self,
        order_service: OrderService,
        inventory_service: InventoryService,
    ):
        self._order_service = order_service
        self._inventory_service = inventory_service

    @transaction.atomic
    def execute(self, input_dto: CreateOrderInput) -> CreateOrderOutput:
        # Validate
        is_valid, error = self._inventory_service.validate_availability(input_dto.items)
        if not is_valid:
            return CreateOrderOutput(success=False, error=error)

        # Execute
        order = self._order_service.create(
            customer_id=input_dto.customer_id,
            items=input_dto.items,
        )
        return CreateOrderOutput(success=True, order_id=order.id)
服务模式:
python
class OrderService:
    # STATIC methods for QUERIES (no state changes)
    @staticmethod
    def get_by_id(order_id: UUID) -> Order | None:
        return Order.objects.select_related('customer').filter(id=order_id).first()

    # INSTANCE methods for MUTATIONS (state changes)
    def create(self, customer_id: UUID, items: list[OrderItemInput]) -> Order:
        order = Order.objects.create(customer_id=customer_id)
        for item in items:
            OrderItem.objects.create(order=order, **item.__dict__)
        return order

    # VALIDATION returns tuple[bool, str]
    def validate_can_cancel(self, order: Order) -> tuple[bool, str]:
        if order.status == Order.Status.SHIPPED:
            return False, "Cannot cancel shipped orders"
        return True, ""
轻量视图模式:
python
class CreateOrderView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request: Request) -> Response:
        serializer = CreateOrderSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        use_case = CreateOrderUseCase(
            order_service=OrderService(),
            inventory_service=InventoryService(),
        )
        input_dto = CreateOrderInput(**serializer.validated_data)
        output = use_case.execute(input_dto)

        if not output.success:
            return Response({'error': output.error}, status=400)
        return Response({'order_id': str(output.order_id)}, status=201)
序列化器分离:
python
undefined

WRITE serializer (input validation)

WRITE serializer (input validation)

class CreateOrderSerializer(serializers.Serializer): items = OrderItemInputSerializer(many=True, min_length=1) notes = serializers.CharField(max_length=500, required=False)
class CreateOrderSerializer(serializers.Serializer): items = OrderItemInputSerializer(many=True, min_length=1) notes = serializers.CharField(max_length=500, required=False)

READ serializer (output display)

READ serializer (output display)

class OrderReadSerializer(serializers.ModelSerializer): customer_name = serializers.CharField(source='customer.name', read_only=True)
class Meta:
    model = Order
    fields = ['id', 'customer_name', 'status', 'created_at']
    read_only_fields = fields

**Model with Domain Logic:**
```python
class Order(models.Model):
    class Status(models.TextChoices):
        PENDING = 'pending', 'Pending'
        CONFIRMED = 'confirmed', 'Confirmed'
        SHIPPED = 'shipped', 'Shipped'

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    customer = models.ForeignKey('Customer', on_delete=models.PROTECT, related_name='orders')
    status = models.CharField(max_length=20, choices=Status.choices, default=Status.PENDING)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [models.Index(fields=['customer', 'status'])]

    @property
    def is_cancellable(self) -> bool:
        return self.status in (self.Status.PENDING, self.Status.CONFIRMED)
class OrderReadSerializer(serializers.ModelSerializer): customer_name = serializers.CharField(source='customer.name', read_only=True)
class Meta:
    model = Order
    fields = ['id', 'customer_name', 'status', 'created_at']
    read_only_fields = fields

**包含领域逻辑的模型:**
```python
class Order(models.Model):
    class Status(models.TextChoices):
        PENDING = 'pending', 'Pending'
        CONFIRMED = 'confirmed', 'Confirmed'
        SHIPPED = 'shipped', 'Shipped'

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    customer = models.ForeignKey('Customer', on_delete=models.PROTECT, related_name='orders')
    status = models.CharField(max_length=20, choices=Status.choices, default=Status.PENDING)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [models.Index(fields=['customer', 'status'])]

    @property
    def is_cancellable(self) -> bool:
        return self.status in (self.Status.PENDING, self.Status.CONFIRMED)

4. Validate and Finalize

4. 验证并最终确认

Architecture Checklist:
  • Views are thin (< 20 lines of logic)
  • Use cases handle single operations
  • Services contain reusable domain logic
  • Dependencies flow inward only
  • No circular imports between layers
Code Quality Checklist:
  • Type hints on all public interfaces
  • Dataclass DTOs are frozen with slots
  • No exceptions for business logic errors → return Output
  • Validation returns
    tuple[bool, str]
  • @transaction.atomic
    wraps state changes
Performance Checklist:
  • select_related
    for ForeignKey access
  • prefetch_related
    for reverse relations
  • Indexes on frequently queried fields
  • No N+1 queries in serializers
架构检查清单:
  • 视图轻量(逻辑代码少于20行)
  • 用例仅处理单个操作
  • 服务包含可复用的领域逻辑
  • 依赖仅向内流动
  • 层之间无循环导入
代码质量检查清单:
  • 所有公共接口都有类型提示
  • 数据类DTO采用冻结模式并使用slots
  • 业务逻辑错误不使用异常,而是返回Output对象
  • 验证逻辑返回
    tuple[bool, str]
    格式
  • 状态变更使用
    @transaction.atomic
    包裹
性能检查清单:
  • 访问ForeignKey时使用
    select_related
  • 处理反向关联时使用
    prefetch_related
  • 为频繁查询的字段添加索引
  • 序列化器中无N+1查询问题

Directory Structure

目录结构

apps/<app_name>/
├── __init__.py
├── models.py              # Domain entities with @property logic
├── views.py               # Thin HTTP handlers
├── serializers.py         # Read and Write serializers
├── urls.py                # Route definitions
├── admin.py               # Django Admin
├── services/
│   ├── __init__.py        # Export services
│   └── <entity>_service.py
├── use_cases/
│   ├── __init__.py        # Export use cases
│   └── <action>_<entity>.py  # One file per use case
├── tests/
│   ├── __init__.py
│   ├── test_models.py
│   ├── test_services.py
│   ├── test_use_cases.py
│   ├── test_views.py
│   └── factories.py       # Factory Boy factories
└── migrations/
apps/<app_name>/
├── __init__.py
├── models.py              # 包含@property逻辑的领域实体
├── views.py               # 轻量HTTP处理器
├── serializers.py         # 读写分离的序列化器
├── urls.py                # 路由定义
├── admin.py               # Django Admin后台
├── services/
│   ├── __init__.py        # 导出服务类
│   └── <entity>_service.py
├── use_cases/
│   ├── __init__.py        # 导出用例类
│   └── <action>_<entity>.py  # 每个用例对应一个文件
├── tests/
│   ├── __init__.py
│   ├── test_models.py
│   ├── test_services.py
│   ├── test_use_cases.py
│   ├── test_views.py
│   └── factories.py       # Factory Boy工厂类
└── migrations/

Bundled Resources

内置资源

references/ - Comprehensive Clean Architecture and API documentation
references/ - 完整的Clean Architecture和API相关文档

Architecture Patterns

架构模式

  • references/project-structure.md
    Directory layout, file naming, module organization, dependency rules
  • references/use-cases-pattern.md
    Input/Output DTOs, constructor injection, transaction handling, error handling
  • references/services-pattern.md
    Static vs instance methods, validation patterns, cross-service communication
  • references/models-domain.md
    Domain logic in models, TextChoices, UUID keys, indexes
  • references/views-serializers.md
    Thin views, permissions, Read vs Write serializers
  • references/testing-clean-arch.md
    Unit testing use cases, mocking services, integration tests
  • references/examples.md
    Complete CRUD example, complex workflows, testing examples
  • references/project-structure.md
    目录布局、文件命名、模块组织、依赖规则
  • references/use-cases-pattern.md
    输入/输出DTO、构造函数注入、事务处理、错误处理
  • references/services-pattern.md
    静态方法与实例方法、验证模式、跨服务通信
  • references/models-domain.md
    模型中的领域逻辑、TextChoices、UUID主键、索引
  • references/views-serializers.md
    轻量视图、权限控制、读写分离的序列化器
  • references/testing-clean-arch.md
    用例单元测试、服务Mock、集成测试
  • references/examples.md
    完整CRUD示例、复杂工作流、测试示例

API Best Practices

API最佳实践

  • references/query-optimization.md
    N+1 queries, select_related/prefetch_related, indexes, bulk operations, aggregations
  • references/api-patterns.md
    Pagination, filtering, searching, ordering, API versioning, error handling, throttling
  • references/authentication.md
    JWT authentication, permissions, API keys, role-based access, security headers
  • references/production-api.md
    Settings structure, database config, caching, logging, Sentry, health checks, Docker
  • references/django-admin.md
    ModelAdmin configuration, inlines, custom actions, query optimization, permissions, security
  • references/query-optimization.md
    N+1查询问题、select_related/prefetch_related、索引、批量操作、聚合查询
  • references/api-patterns.md
    分页、过滤、搜索、排序、API版本控制、错误处理、限流
  • references/authentication.md
    JWT认证、权限控制、API密钥、基于角色的访问控制、安全头
  • references/production-api.md
    配置结构、数据库配置、缓存、日志、Sentry、健康检查、Docker
  • references/django-admin.md
    ModelAdmin配置、内联组件、自定义动作、查询优化、权限控制、安全

Code Quality

代码质量

  • references/coding-standards.md
    Ruff configuration, import ordering, security practices, YAGNI, logging, documentation
  • references/coding-standards.md
    Ruff配置、导入排序、安全实践、YAGNI原则、日志、文档

Core Principles

核心原则

No Exceptions for Business Logic

业务逻辑不使用异常

python
undefined
python
undefined

BAD

不良实践

def create_order(self, data): if not self.can_create(): raise ValidationError("Cannot create order") return Order.objects.create(**data)
def create_order(self, data): if not self.can_create(): raise ValidationError("Cannot create order") return Order.objects.create(**data)

GOOD

最佳实践

def create_order(self, data) -> CreateOrderOutput: if not self.can_create(): return CreateOrderOutput(success=False, error="Cannot create order") order = Order.objects.create(**data) return CreateOrderOutput(success=True, order_id=order.id)
undefined
def create_order(self, data) -> CreateOrderOutput: if not self.can_create(): return CreateOrderOutput(success=False, error="Cannot create order") order = Order.objects.create(**data) return CreateOrderOutput(success=True, order_id=order.id)
undefined

Validation Returns Tuples

验证逻辑返回元组

python
undefined
python
undefined

BAD

不良实践

def validate(self, order) -> bool: return order.status != 'shipped'
def validate(self, order) -> bool: return order.status != 'shipped'

GOOD

最佳实践

def validate(self, order) -> tuple[bool, str]: if order.status == 'shipped': return False, "Cannot modify shipped orders" return True, ""
undefined
def validate(self, order) -> tuple[bool, str]: if order.status == 'shipped': return False, "Cannot modify shipped orders" return True, ""
undefined

Constructor Injection for Testability

构造函数注入提升可测试性

python
undefined
python
undefined

BAD - Hard to test

不良实践 - 难以测试

class CreateOrderUseCase: def execute(self, input_dto): service = OrderService() # Hardcoded dependency return service.create(input_dto)
class CreateOrderUseCase: def execute(self, input_dto): service = OrderService() # 硬编码依赖 return service.create(input_dto)

GOOD - Easy to mock

最佳实践 - 易于Mock

class CreateOrderUseCase: def init(self, order_service: OrderService): self._order_service = order_service
def execute(self, input_dto):
    return self._order_service.create(input_dto)
undefined
class CreateOrderUseCase: def init(self, order_service: OrderService): self._order_service = order_service
def execute(self, input_dto):
    return self._order_service.create(input_dto)
undefined

Additional Notes

补充说明

Python Version: 3.10+ required (for
X | None
union syntax), 3.12+ recommended Django Version: 4.2 LTS minimum, 5.0+ recommended
Naming Conventions:
  • Use cases:
    <action>_<entity>.py
    (e.g.,
    create_order.py
    )
  • Services:
    <entity>_service.py
    (e.g.,
    order_service.py
    )
  • Serializers:
    <Entity>ReadSerializer
    ,
    <Entity>CreateSerializer
Integration with Other Skills:
  • Use
    django-celery-expert
    for background tasks
  • Use
    refactordjango
    to migrate existing code to this architecture
Python版本: 要求Python 3.10+(支持
X | None
联合类型语法),推荐使用3.12+ Django版本: 最低要求Django 4.2 LTS,推荐使用5.0+
命名规范:
  • 用例:
    <action>_<entity>.py
    (例如:
    create_order.py
  • 服务:
    <entity>_service.py
    (例如:
    order_service.py
  • 序列化器:
    <Entity>ReadSerializer
    <Entity>CreateSerializer
与其他Skill的集成:
  • 如需处理后台任务,请使用
    django-celery-expert
  • 如需将现有代码迁移到本架构,请使用
    refactordjango