mcpField
D
django-patterns

django-patterns

github.com/rohitg00開発2.8k181 回インストール24 週間前に更新
リポジトリ

django-patterns について

Django 開発者向けの設計パターンガイドです。プロジェクトのレイヤー構成、ORM クエリの最適化、REST Framework のシリアライザー、ミドルウェアを扱い、シグナルの用途やテスト項目も示します。

主な機能

  1. 01プロジェクト構成とビジネスロジックの分離
  2. 02select_related と prefetch_related
  3. 03REST Framework シリアライザー
  4. 04アプリ間の副作用とシグナル
  5. 05カスタムミドルウェアのパターン
  6. 06アンチパターンとテスト項目

活用シーン

  1. 01Django プロジェクトのモジュール構成の計画
  2. 02ORM の N+1 クエリ問題の削減
  3. 03API のシリアライズと入力検証の設計
  4. 04ビュー、シグナル、テスト実践の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rohitg00/awesome-claude-code-toolkit --skill django-patterns

インストール後、Claude Code で/django-patternsを入力して読み込まれたか確認します。

詳細

Django のパターン

プロジェクト構成

アプリ、共通ユーティリティ、設定を明確に分けて、Django プロジェクトを構成します。

project/
  config/
    settings/
      base.py
      local.py
      production.py
    urls.py
    wsgi.py
  apps/
    users/
      models.py
      serializers.py
      views.py
      services.py
      selectors.py
      urls.py
      tests/
    orders/
      ...
  common/
    models.py
    permissions.py
    pagination.py

書き込み処理は services.py に、読み取り処理は selectors.py にビジネスロジックを記述します。ビューは薄く保ちます。

ORM の最適化

# select_related for ForeignKey / OneToOne (SQL JOIN)
orders = Order.objects.select_related("customer", "customer__profile").all()

# prefetch_related for ManyToMany / reverse FK (separate query)
authors = Author.objects.prefetch_related(
    Prefetch("books", queryset=Book.objects.filter(published=True))
).all()

# Defer fields you don't need
posts = Post.objects.defer("body", "metadata").filter(status="published")

# Use .only() when you need just a few columns
emails = User.objects.only("id", "email").filter(is_active=True)

# Bulk operations
Product.objects.bulk_create(products, batch_size=1000)
Product.objects.bulk_update(products, ["price", "stock"], batch_size=1000)

テストでは必ず django-debug-toolbar または connection.queries を使ってクエリを確認します。

Django REST Framework のシリアライザー

class OrderSerializer(serializers.ModelSerializer):
    customer_name = serializers.CharField(source="customer.full_name", read_only=True)
    items = OrderItemSerializer(many=True, read_only=True)
    total = serializers.SerializerMethodField()

    class Meta:
        model = Order
        fields = ["id", "customer_name", "items", "total", "created_at"]
        read_only_fields = ["id", "created_at"]

    def get_total(self, obj):
        return sum(item.price * item.quantity for item in obj.items.all())

    def validate(self, data):
        if data.get("start_date") and data.get("end_date"):
            if data["start_date"] >= data["end_date"]:
                raise serializers.ValidationError("end_date must be after start_date")
        return data

シグナル

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Order)
def order_created_handler(sender, instance, created, **kwargs):
    if created:
        send_order_confirmation.delay(instance.id)
        update_inventory.delay(instance.id)

アプリ間の副作用にはシグナルを使用します。同じアプリ内のロジックでは、サービスを直接呼び出します。

カスタムミドルウェア

import time
import logging

logger = logging.getLogger(__name__)

class RequestTimingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        start = time.monotonic()
        response = self.get_response(request)
        duration = time.monotonic() - start
        logger.info(f"{request.method} {request.path} {response.status_code} {duration:.3f}s")
        return response

アンチパターン

  • サービスレイヤーではなく、ビューやシリアライザーにビジネスロジックを記述する
  • リストエンドポイントでページネーションを使わずに Model.objects.all() を使用する
  • select_related / prefetch_related の指定漏れによる N+1 クエリ
  • 同じアプリ内のロジックでシグナルを使いすぎる(処理の流れを追いにくくする)
  • 環境変数ではなく、settings.py にシークレットを保存する
  • パラメーター化クエリを使わずに生の SQL を実行する

チェックリスト

  • ビジネスロジックがビューではなく、サービスやセレクターに記述されている
  • 必要に応じて、すべてのリストクエリで select_related または prefetch_related を使用している
  • シリアライザーがカスタム validate メソッドで入力データを検証している
  • 設定が base/local/production の各モジュールに分割されている
  • マージ前にマイグレーションがレビューされている
  • 一括挿入・更新に一括操作を使用している
  • カスタムミドルウェアが WSGI 呼び出し可能オブジェクトのパターンに従っている
  • テストでモデルの制約、シリアライザーの検証、ビューの権限を網羅している

コメント