jpskill.com
🛠️ 開発・MCP コミュニティ

django-clean-drf

Clean ArchitectureとSOLID原則に基づき、Django REST Frameworkで高品質なAPIを構築し、レイヤー構造、クエリ最適化、認証認可、本番環境へのデプロイまでを網羅的に支援するSkill。

📜 元の英語説明(参考)

Create production-quality Django REST Framework APIs using Clean Architecture and SOLID principles. Covers layered architecture (views, use cases, services, models), query optimization (N+1 prevention), pagination/filtering, JWT authentication, permissions, and production deployment. Use when building new Django APIs, implementing domain-driven design, optimizing queries, or configuring authentication. Applies Python 3.12+ and Django 5+ patterns.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Clean ArchitectureとSOLID原則に基づき、Django REST Frameworkで高品質なAPIを構築し、レイヤー構造、クエリ最適化、認証認可、本番環境へのデプロイまでを網羅的に支援するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o django-clean-drf.zip https://jpskill.com/download/10594.zip && unzip -o django-clean-drf.zip && rm django-clean-drf.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10594.zip -OutFile "$d\django-clean-drf.zip"; Expand-Archive "$d\django-clean-drf.zip" -DestinationPath $d -Force; ri "$d\django-clean-drf.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して django-clean-drf.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → django-clean-drf フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Django Clean DRF Architect

概要

このスキルは、Clean Architecture の原則に従って Django REST Framework アプリケーションを作成するための専門的なガイダンスを提供します。関心の分離、テスト容易性の最大化、および保守可能な本番品質のコードの生成を可能にする、厳密な階層化アーキテクチャを適用します。

アーキテクチャのレイヤー:

HTTP Layer (Views/Serializers)
    ↓
Application Layer (Use Cases + DTOs)
    ↓
Domain Layer (Services + Models)
    ↓
Infrastructure Layer (ORM, External APIs, Cache)

主な機能:

  • 厳密な依存関係ルール(依存関係は内側に向かってのみ流れる)を持つ階層化アーキテクチャ
  • dataclass の Input/Output DTO を使用した Use Case パターン
  • ドメインロジックのための Service レイヤー(静的クエリ、インスタンスの変更)
  • Use Case に委譲する薄い View
  • 読み取りと作成/更新のための別々の Serializer
  • ビジネスロジックのための例外を使用しない明示的なエラー処理
  • 最新の Python 3.12+ および Django 5+ の機能
  • 完全な型ヒントと設計によるテスト容易性

どのような時に使うか

以下のトリガーが発生した場合に、このスキルを呼び出してください。

新規アプリケーションのセットアップ:

  • 「...のための新しい Django API を作成する」
  • 「Clean Architecture を使用して新しい DRF プロジェクトを開始する」
  • 「階層化アーキテクチャを使用して新しいアプリをセットアップする」
  • 「ドメイン駆動の Django アプリケーションを初期化する」
  • 「SOLID に従って Django アプリをスキャフォールドする」

Use Case の実装:

  • 「...のための Use Case を作成する」
  • 「...のためのビジネスロジックを実装する」
  • 「...のための新しい操作/アクションを追加する」
  • 「このトランザクションをアトミックに処理する」

Service レイヤー:

  • 「...のための Service を作成する」
  • 「このビジネスロジックはどこに配置すべきか?」
  • 「...のためのドメインバリデーションを実装する」
  • 「Clean Architecture に従ってデータをクエリする」

アーキテクチャに関する質問:

  • 「この Django アプリをどのように構成すればよいか?」
  • 「どのレイヤーが...を処理すべきか?」
  • 「肥大化した View/Model をどのように回避するか?」
  • 「これをどのようにテスト可能にするか?」
  • 「Django に SOLID 原則を適用する」

API 設計:

  • 「...のための API エンドポイントを作成する」
  • 「...のための Serializer を設計する」
  • 「このエンティティのための CRUD を実装する」

指示

Django Clean DRF のリクエストを処理する際は、以下のワークフローに従ってください。

1. 要件の分析とコンテキストの確立

ドメインを理解する:

  • どのようなエンティティ/モデルが関係しているか?
  • どのような操作/アクションが必要か?
  • どのようなビジネスルールを適用する必要があるか?
  • 外部依存関係(API、キュー)はあるか?

既存のプロジェクト構造を確認する:

  • 既存のアプリとその構成を確認する
  • すでに使用されているパターンを特定する
  • 機能の可用性について Django/Python のバージョンを確認する

スコープを決定する:

  • 単一の Use Case か、完全な CRUD か?
  • 新しいアプリか、既存のアプリの拡張か?
  • API のみか、管理画面も含むか?

2. 関連する参照ドキュメントをロードする

タスクに基づいて、適切なバンドルされたドキュメントを参照してください。

アーキテクチャ:

  • 新規アプリのセットアップreferences/project-structure.md
  • Use Case の実装references/use-cases-pattern.md
  • Service レイヤーreferences/services-pattern.md
  • モデルとドメインロジックreferences/models-domain.md
  • View と Serializerreferences/views-serializers.md
  • テストreferences/testing-clean-arch.md
  • 完全な例references/examples.md

API 開発:

  • クエリの最適化 / N+1references/query-optimization.md
  • ページネーション、フィルタリング、検索references/api-patterns.md
  • 認証 / JWT / パーミッションreferences/authentication.md
  • 本番環境へのデプロイreferences/production-api.md
  • API 用の Django Adminreferences/django-admin.md

コード品質:

  • コーディング標準 / Ruff / セキュリティreferences/coding-standards.md

3. Clean Architecture の原則に従って実装する

重要: レイヤーの依存関係ルール

Views → Use Cases → Services → Models
  ↓         ↓           ↓         ↓
Serializers  DTOs    (internal)   ORM
  • 依存関係は内側に向かってのみ流れる(外側のレイヤーは内側のレイヤーに依存する)
  • Use CaseView をインポートしたり、ServiceUse Case をインポートしたりしてはいけない

Use Case パターン:

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 パターン:

class OrderService:
    # クエリのための STATIC メソッド(状態変化なし)
    @staticmethod
    def get_by_id(order_id: UUID) -> Order | None:
        return Order.objects.select_related('customer').filter(id=order_id).first()

    # 変更のための INSTANCE メソッド(状態変化あり)
    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

    # バリデーションは 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 パターン:

class CreateOrderView(APIView):
    permission_classes = [Is
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Django Clean DRF Architect

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

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"

Instructions

Follow this workflow when handling Django Clean DRF requests:

1. Analyze Requirements and Establish Context

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?

2. Load Relevant Reference Documentation

Based on the task, reference the appropriate bundled documentation:

Architecture:

  • New app setupreferences/project-structure.md
  • Use case implementationreferences/use-cases-pattern.md
  • Service layerreferences/services-pattern.md
  • Models and domain logicreferences/models-domain.md
  • Views and serializersreferences/views-serializers.md
  • Testingreferences/testing-clean-arch.md
  • Complete examplesreferences/examples.md

API Development:

  • Query optimization / N+1references/query-optimization.md
  • Pagination, filtering, searchreferences/api-patterns.md
  • Authentication / JWT / Permissionsreferences/authentication.md
  • Production deploymentreferences/production-api.md
  • Django Admin for APIsreferences/django-admin.md

Code Quality:

  • Coding standards / Ruff / Securityreferences/coding-standards.md

3. Implement Following Clean Architecture Principles

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:

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:

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:

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:

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

# 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:

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

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

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/

Bundled Resources

references/ - Comprehensive Clean Architecture and API documentation

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

API Best Practices

  • 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

Code Quality

  • references/coding-standards.md Ruff configuration, import ordering, security practices, YAGNI, logging, documentation

Core Principles

No Exceptions for Business Logic

# BAD
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)

Validation Returns Tuples

# BAD
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, ""

Constructor Injection for Testability

# BAD - Hard to test
class CreateOrderUseCase:
    def execute(self, input_dto):
        service = OrderService()  # Hardcoded dependency
        return service.create(input_dto)

# GOOD - Easy to 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)

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