django-drf について
Django REST Framework API の構築向け開発スキルです。ビュー、シリアライザー、フィルタリング、権限、ページネーション、ルーティング、テストのパターンを紹介します。
主な機能
- 01ViewSet のパターン
- 02シリアライザーの例
- 03フィルタリングと権限
- 04ページネーションと URL ルーティング
- 05API テストの例
- 06Django 管理コマンド
活用シーン
- 01CRUD API エンドポイントの実装
- 02API 結果のフィルタリングとページ分割
- 03オブジェクト単位の権限設定
- 04API ビューのテスト
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ gentleman-programming/ gentleman-skills --skill django-drfインストール後、Claude Code で/django-drfを入力して読み込まれたか確認します。
詳細
ViewSet パターン
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
filterset_class = UserFilter
permission_classes = [IsAuthenticated]
def get_serializer_class(self):
if self.action == "create":
return UserCreateSerializer
if self.action in ["update", "partial_update"]:
return UserUpdateSerializer
return UserSerializer
@action(detail=True, methods=["post"])
def activate(self, request, pk=None):
user = self.get_object()
user.is_active = True
user.save()
return Response({"status": "activated"})
シリアライザーパターン
from rest_framework import serializers
# Read Serializer
class UserSerializer(serializers.ModelSerializer):
full_name = serializers.SerializerMethodField()
class Meta:
model = User
fields = ["id", "email", "full_name", "created_at"]
read_only_fields = ["id", "created_at"]
def get_full_name(self, obj):
return f"{obj.first_name} {obj.last_name}"
# Create Serializer
class UserCreateSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ["email", "password", "first_name", "last_name"]
def create(self, validated_data):
password = validated_data.pop("password")
user = User(**validated_data)
user.set_password(password)
user.save()
return user
# Update Serializer
class UserUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ["first_name", "last_name"]
フィルター
from django_filters import rest_framework as filters
class UserFilter(filters.FilterSet):
email = filters.CharFilter(lookup_expr="icontains")
is_active = filters.BooleanFilter()
created_after = filters.DateTimeFilter(
field_name="created_at",
lookup_expr="gte"
)
created_before = filters.DateTimeFilter(
field_name="created_at",
lookup_expr="lte"
)
class Meta:
model = User
fields = ["email", "is_active"]
権限
from rest_framework.permissions import BasePermission
class IsOwner(BasePermission):
def has_object_permission(self, request, view, obj):
return obj.owner == request.user
class IsAdminOrReadOnly(BasePermission):
def has_permission(self, request, view):
if request.method in ["GET", "HEAD", "OPTIONS"]:
return True
return request.user.is_staff
ページネーション
from rest_framework.pagination import PageNumberPagination
class StandardPagination(PageNumberPagination):
page_size = 20
page_size_query_param = "page_size"
max_page_size = 100
# settings.py
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "api.pagination.StandardPagination",
}
URL ルーティング
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r"users", UserViewSet, basename="user")
router.register(r"posts", PostViewSet, basename="post")
urlpatterns = [
path("api/v1/", include(router.urls)),
]
テスト
import pytest
from rest_framework import status
from rest_framework.test import APIClient
@pytest.fixture
def api_client():
return APIClient()
@pytest.fixture
def authenticated_client(api_client, user):
api_client.force_authenticate(user=user)
return api_client
@pytest.mark.django_db
class TestUserViewSet:
def test_list_users(self, authenticated_client):
response = authenticated_client.get("/api/v1/users/")
assert response.status_code == status.HTTP_200_OK
def test_create_user(self, authenticated_client):
data = {"email": "[email protected]", "password": "pass123"}
response = authenticated_client.post("/api/v1/users/", data)
assert response.status_code == status.HTTP_201_CREATED
コマンド
python manage.py runserver
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py shell
キーワード
django, drf, rest framework, viewset, serializer, api, rest api
コメント
Markdown 対応