{"id":"django-expert","name":"django-expert","summary":"Django REST FrameworkでDjangoのウェブアプリケーションやREST APIを構築する際に使うことができます。","body":"# Django Expert\n\nSenior Django specialist with deep expertise in Django 5.0, Django REST Framework, and production-grade web applications.\n\n## When to Use This Skill\n\n- Building Django web applications or REST APIs\n- Designing Django models with proper relationships\n- Implementing DRF serializers and viewsets\n- Optimizing Django ORM queries\n- Setting up authentication (JWT, session)\n- Django admin customization\n\n## Core Workflow\n\n1. **Analyze requirements** — Identify models, relationships, API endpoints\n2. **Design models** — Create models with proper fields, indexes, managers → run `manage.py makemigrations` and `manage.py migrate`; verify schema before proceeding\n3. **Implement views** — DRF viewsets or Django 5.0 async views\n4. **Validate endpoints** — Confirm each endpoint returns expected status codes with a quick `APITestCase` or `curl` check before adding auth\n5. **Add auth** — Permissions, JWT authentication\n6. **Test** — Django TestCase, APITestCase\n\n## Reference Guide\n\nLoad detailed guidance based on context:\n\n| Topic | Reference | Load When |\n|-------|-----------|-----------|\n| Models | `references/models-orm.md` | Creating models, ORM queries, optimization |\n| Serializers | `references/drf-serializers.md` | DRF serializers, validation |\n| ViewSets | `references/viewsets-views.md` | Views, viewsets, async views |\n| Authentication | `references/authentication.md` | JWT, permissions, SimpleJWT |\n| Testing | `references/testing-django.md` | APITestCase, fixtures, factories |\n\n## Minimal Working Example\n\nThe snippet below demonstrates the core MUST DO constraints: indexed fields, `select_related`, serializer validation, and endpoint permissions.\n\n```python\n# models.py\nfrom django.db import models\n\nclass Article(models.Model):\n    title = models.CharField(max_length=255, db_index=True)\n    author = models.ForeignKey(\n        \"auth.User\", on_delete=models.CASCADE, related_name=\"articles\"\n    )\n    published_at = models.DateTimeField(auto_now_add=True, db_index=True)\n\n    class Meta:\n        ordering = [\"-published_at\"]\n        indexes = [models.Index(fields=[\"author\", \"published_at\"])]\n\n    def __str__(self):\n        return self.title\n\n# serializers.py\nfrom rest_framework import serializers\nfrom .models import Article\n\nclass ArticleSerializer(serializers.ModelSerializer):\n    author_username = serializers.CharField(source=\"author.username\", read_only=True)\n\n    class Meta:\n        model = Article\n        fields = [\"id\", \"title\", \"author_username\", \"published_at\"]\n\n    def validate_title(self, value):\n        if len(value.strip()) < 3:\n            raise serializers.ValidationError(\"Title must be at least 3 characters.\")\n        return value.strip()\n\n# views.py\nfrom rest_framework import viewsets, permissions\nfrom .models import Article\nfrom .serializers import ArticleSerializer\n\nclass ArticleViewSet(viewsets.ModelViewSet):\n    \"\"\"\n    Uses select_related to avoid N+1 on author lookups.\n    IsAuthenticatedOrReadOnly: safe methods are public, writes require auth.\n    \"\"\"\n    serializer_class = ArticleSerializer\n    permission_classes = [permissions.IsAuthenticatedOrReadOnly]\n\n    def get_queryset(self):\n        return Article.objects.select_related(\"author\").all()\n\n    def perform_create(self, serializer):\n        serializer.save(author=self.request.user)\n```\n\n```python\n# tests.py\nfrom rest_framework.test import APITestCase\nfrom rest_framework import status\nfrom django.contrib.auth.models import User\n\nclass ArticleAPITest(APITestCase):\n    def setUp(self):\n        self.user = User.objects.create_user(\"alice\", password=\"pass\")\n\n    def test_list_public(self):\n        res = self.client.get(\"/api/articles/\")\n        self.assertEqual(res.status_code, status.HTTP_200_OK)\n\n    def test_create_requires_auth(self):\n        res = self.client.post(\"/api/articles/\", {\"title\": \"Test\"})\n        self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)\n\n    def test_create_authenticated(self):\n        self.client.force_authenticate(self.user)\n        res = self.client.post(\"/api/articles/\", {\"title\": \"Hello Django\"})\n        self.assertEqual(res.status_code, status.HTTP_201_CREATED)\n```\n\n## Constraints\n\n### MUST DO\n- Use `select_related`/`prefetch_related` for related objects\n- Add database indexes for frequently queried fields\n- Use environment variables for secrets\n- Implement proper permissions on all endpoints\n- Write tests for models and API endpoints\n- Use Django's built-in security features (CSRF, etc.)\n\n### MUST NOT DO\n- Use raw SQL without parameterization\n- Skip database migrations\n- Store secrets in settings.py\n- Use DEBUG=True in production\n- Trust user input without validation\n- Ignore query optimization\n\n## Output Templates\n\nWhen implementing Django features, provide:\n1. Model definitions with indexes\n2. Serializers with validation\n3. ViewSet or views with permissions\n4. Brief note on query optimization\n\n## Knowledge Reference\n\nDjango 5.0, DRF, async views, ORM, QuerySet, select_related, prefetch_related, SimpleJWT, django-filter, drf-spectacular, pytest-django\n\n[Documentation](https://jeffallan.github.io/claude-skills/skills/backend/django-expert/)","author":"@Jeffallan","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/Jeffallan/claude-skills/tree/main/skills/django-expert","license":"MIT","category":"coding","lang":"en","tokens":1109,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/authentication.md","size":3962,"sha256":"1c8cb67744898fadca804fb262e25bf0fc3ee4e094ff920b00ae0be9ee5925a8"},{"path":"references/drf-serializers.md","size":4132,"sha256":"0642b28b45e28c367f3b897c565abc1a9dd743a67bc0330a9acbd1a3bf6ee5ff"},{"path":"references/models-orm.md","size":3886,"sha256":"82169cfe80c42aaa0a90d5ec0fc3813ba4c6e2db181eaa84562a53e4e9de17f9"},{"path":"references/testing-django.md","size":5519,"sha256":"102514fbde3e8fd950446823c251793021162b75f6961773b481665679fddd63"},{"path":"references/viewsets-views.md","size":4305,"sha256":"48ce90f17330f60b58a8f948cfcd7323f67dd446d0cc16cbce3c1313748574e7"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["jeffallan.github.io"]}}