mcpField
D
django-coder

django-coder

github.com/majesticlabs-dev開発5065 回インストール7 週間前に更新
リポジトリ

django-coder について

Django で Web アプリケーションを開発する人向けのスキルです。プロジェクト構成、モデル、ビュー、API のパターンと例を示します。

主な機能

  1. 01標準的な Django 構成
  2. 02モデルとマネージャーのパターン
  3. 03クラスベースビューと非同期ビュー
  4. 04Django REST Framework の例
  5. 05サービス層と品質チェックリスト

活用シーン

  1. 01新しい Django プロジェクトの構成
  2. 02ビジネスロジックとビューの整理
  3. 03Django REST Framework による REST エンドポイントの構築

インストール

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

$npx skills add https://github.com/majesticlabs-dev/majestic-marketplace --skill django-coder

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

詳細

Django Coder

基本原則

原則適用方法
設定より規約Django の標準的なプロジェクト構成に従う
DRYモデルの継承、ミックスイン、テンプレートの継承を使用する
ファットモデル、シンビュービジネスロジックはモデルやマネージャーに記述し、ビューは処理を調整するだけにする
セキュリティを最優先CSRF、SQL インジェクション対策、XSS 防止機能が組み込まれている
暗黙的より明示的URL ルーティングを明確にし、インポートを明示する

プロジェクト構成

project/
├── manage.py
├── config/                  # Project settings
│   ├── __init__.py
│   ├── settings/
│   │   ├── base.py
│   │   ├── local.py
│   │   └── production.py
│   ├── urls.py
│   └── wsgi.py
├── apps/
│   └── users/              # App per domain
│       ├── __init__.py
│       ├── admin.py
│       ├── apps.py
│       ├── forms.py
│       ├── models.py
│       ├── urls.py
│       ├── views.py
│       ├── services.py     # Business logic
│       ├── selectors.py    # Query logic
│       └── tests/
├── templates/
│   ├── base.html
│   └── users/
└── static/

モデル

モデルの定義
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    """Custom user model."""
    bio = models.TextField(blank=True)
    avatar = models.ImageField(upload_to="avatars/", blank=True)

    class Meta:
        ordering = ["-date_joined"]

    def __str__(self):
        return self.email

class Post(models.Model):
    """Blog post model."""
    class Status(models.TextChoices):
        DRAFT = "draft", "Draft"
        PUBLISHED = "published", "Published"

    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts")
    content = models.TextField()
    status = models.CharField(max_length=10, choices=Status.choices, default=Status.DRAFT)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        indexes = [
            models.Index(fields=["slug"]),
            models.Index(fields=["status", "-created_at"]),
        ]
カスタムマネージャー
class PublishedManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status=Post.Status.PUBLISHED)

class Post(models.Model):
    # ... fields ...
    objects = models.Manager()
    published = PublishedManager()

ビュー

クラスベースビュー
from django.views.generic import ListView, DetailView, CreateView, UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy

class PostListView(ListView):
    model = Post
    queryset = Post.published.all()
    context_object_name = "posts"
    paginate_by = 10
    template_name = "posts/list.html"

class PostDetailView(DetailView):
    model = Post
    slug_field = "slug"
    slug_url_kwarg = "slug"
    template_name = "posts/detail.html"

class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    fields = ["title", "content", "status"]
    template_name = "posts/form.html"
    success_url = reverse_lazy("posts:list")

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)
非同期ビュー(Django 4.1+)
from django.http import JsonResponse
from asgiref.sync import sync_to_async

async def async_post_list(request):
    posts = await sync_to_async(list)(Post.published.all()[:10])
    data = [{"title": p.title, "slug": p.slug} for p in posts]
    return JsonResponse({"posts": data})

Django REST Framework

シリアライザー
from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    author = serializers.StringRelatedField(read_only=True)

    class Meta:
        model = Post
        fields = ["id", "title", "slug", "author", "content", "status", "created_at"]
        read_only_fields = ["slug", "created_at"]

class PostCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ["title", "content", "status"]

    def create(self, validated_data):
        validated_data["author"] = self.context["request"].user
        return super().create(validated_data)
ビューセット
from rest_framework import viewsets, permissions, status
from rest_framework.decorators import action
from rest_framework.response import Response

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    lookup_field = "slug"

    def get_queryset(self):
        if self.action == "list":
            return Post.published.all()
        return Post.objects.all()

    def get_serializer_class(self):
        if self.action == "create":
            return PostCreateSerializer
        return PostSerializer

    @action(detail=True, methods=["post"])
    def publish(self, request, slug=None):
        post = self.get_object()
        post.status = Post.Status.PUBLISHED
        post.save()
        return Response({"status": "published"})

サービスパターン

# apps/posts/services.py
from django.db import transaction
from .models import Post

class PostService:
    @staticmethod
    @transaction.atomic
    def create_post(*, author, title: str, content: str) -> Post:
        post = Post.objects.create(
            author=author,
            title=title,
            content=content,
            status=Post.Status.DRAFT,
        )
        return post

    @staticmethod
    def publish_post(*, post: Post) -> Post:
        post.status = Post.Status.PUBLISHED
        post.save(update_fields=["status", "updated_at"])
        return post

品質チェックリスト

  • プロジェクト開始時にカスタム User モデルを作成する
  • アプリをドメインごとに整理する
  • ファットモデル、シンビューにする
  • 複雑なビジネスロジックにはサービスを使用する
  • クエリ可能なフィールドに適切なインデックスを設定する
  • フォームで CSRF 保護を有効にする
  • 必要な箇所でログインを必須にする
  • ForeignKey に適切な related_name を設定する
  • モデル、ビュー、サービスのテストを作成する

よくある間違い

間違い修正方法
カスタム User モデルがない必ず AbstractUser から始める
ビューにロジックを記述するサービスやモデルに移す
N+1 クエリselect_related/prefetch_related を使用する
インデックスがない絞り込みや並べ替えに使うフィールドにインデックスを追加する
URL をハードコードするreverse() と {% url %} を使用する

コメント