Skip to main content

django-rest-framework

Use when Django REST Framework for building APIs with serializers, viewsets, and authentication. Use when creating RESTful APIs.

소스 정보

저장소
TheBushidoCollective/han
최근 소스 활동
2026년 2월 11일 17:47
감지된 SKILL.md 언어
영어
스타
198
포크
24

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
django-rest-framework
user-invocable
false
description
Use when Django REST Framework for building APIs with serializers, viewsets, and authentication. Use when creating RESTful APIs.
allowed-tools
["Bash","Read"]
# Django REST Framework Master Django REST Framework for building robust, scalable RESTful APIs with proper serialization and authentication. ## Serializers Build type-safe data serialization with Django REST Framework serializers. ```python from rest_framework import serializers from django.contrib.auth.models import User class UserSerializer(serializers.ModelSerializer): post_count = serializers.IntegerField(read_only=True) full_name = serializers.SerializerMethodField() class Meta: model = User fields = ['id', 'email', 'name', 'post_count', 'full_name'] read_only_fields = ['id', 'created_at'] extra_kwargs = { 'email': {'required': True}, 'password': {'write_only': True} } def get_full_name(self, obj): return f"{obj.first_name} {obj.last_name}" class PostSerializer(serializers.ModelSerializer): author = UserSerializer(read_only=True) author_id = serializers.IntegerField(write_only=True) class Meta: model = Post fields = '__all__' def validate_title(self, value): if len(value) < 5: raise serializers.ValidationError('Title must be at least 5 characters') return value def validate(self, data): if data.get('published') and not data.get('content'): raise serializers.ValidationError('Published posts must have content') return data def create(self, validated_data): # Custom creation logic post = Post.objects.create(**validated_data) # Send notification, etc. return post ``` ## Custom Fields and Validation Create custom serializer fields for complex data types. ```python from rest_framework import serializers class Base64ImageField(serializers.ImageField): """Handle base64 encoded images.""" def to_internal_value(self, data): import base64 from django.core.files.base import ContentFile if isinstance(data, str) and data.startswith('data:image'): format, imgstr = data.split(';base64,') ext = format.split('/')[-1] data = ContentFile(base64.b64decode(imgstr), name=f'temp.{ext}') return super().to_internal_value(data) class PostSerializer(serializers.ModelSerializer): image = Base64ImageField(required=False) class Meta: model = Post fields = ['id', 'title', 'image'] # Custom validators def validate_no_profanity(value): profanity_words = ['bad', 'worse'] if any(word in value.lower() for word in profanity_words): raise serializers.ValidationError('Content contains profanity') return value class CommentSerializer(serializers.ModelSerializer): content = serializers.CharField(validators=[validate_no_profanity]) class Meta: model = Comment fields = ['id', 'content', 'created_at'] ``` ## Nested Serializers Handle complex nested relationships. ```python class CommentSerializer(serializers.ModelSerializer): author = UserSerializer(read_only=True) class Meta: model = Comment fields = ['id', 'content', 'author', 'created_at'] class PostSerializer(serializers.ModelSerializer): author = UserSerializer(read_only=True) comments = CommentSerializer(many=True, read_only=True) class Meta: model = Post fields = ['id', 'title', 'content', 'author', 'comments'] # Writable nested serializers class PostCreateSerializer(serializers.ModelSerializer): comments = CommentSerializer(many=True, required=False) class Meta: model = Post fields = ['id', 'title', 'content', 'comments'] def create(self, validated_data): comments_data = validated_data.pop('comments', []) post = Post.objects.create(**validated_data) for comment_data in comments_data: Comment.objects.create(post=post, **comment_data) return post # Dynamic nested serialization class PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = ['id', 'title', 'content'] def __init__(self, *args, **kwargs): include_comments = kwargs.pop('include_comments', False) super().__init__(*args, **kwargs) if include_comments: self.fields['comments'] = CommentSerializer(many=True, read_only=True) ``` ## ViewSets Create RESTful endpoints with ViewSets. ```python 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] filterset_fields = ['author', 'published'] search_fields = ['title', 'content'] ordering_fields = ['created_at', 'title'] def get_queryset(self): queryset = super().get_queryset() if self.action == 'list': queryset = queryset.filter(published=True) return queryset.select_related('author').prefetch_related('comments') def get_serializer_class(self): if self.action == 'create': return PostCreateSerializer return PostSerializer def perform_create(self, serializer): serializer.save(author=self.request.user) @action(detail=True, methods=['post']) def publish(self, request, pk=None): post = self.get_object() post.published = True post.save() return Response({'status': 'published'}) @action(detail=False, methods=['get']) def recent(self, request): recent_posts = self.get_queryset()[:10] serializer = self.get_serializer(recent_posts, many=True) return Response(serializer.data) # ReadOnly ViewSet class CategoryViewSet(viewsets.ReadOnlyModelViewSet): queryset = Category.objects.all() serializer_class = CategorySerializer ``` ## Routers Configure URL routing for ViewSets. ```python from rest_framework.routers import DefaultRouter, SimpleRouter from django.urls import path, include # Default router (with API root view) router = DefaultRouter() router.register(r'posts', PostViewSet, basename='post') router.register(r'users', UserViewSet, basename='user') router.register(r'comments', CommentViewSet, basename='comment') urlpatterns = [ path('api/', include(router.urls)), ] # Simple router (no API root) simple_router = SimpleRouter() simple_router.register(r'posts', PostViewSet) # Custom routing from rest_framework.routers import Route, DynamicRoute class CustomRouter(DefaultRouter): routes = [ Route( url=r'^{prefix}/$', mapping={'get': 'list', 'post': 'create'}, name='{basename}-list', detail=False, initkwargs={} ), # Add custom routes ] ``` ## Permissions Implement authentication and authorization. ```python from rest_framework import permissions class IsAuthorOrReadOnly(permissions.BasePermission): """Custom permission to only allow authors to edit.""" def has_object_permission(self, request, view, obj): # Read permissions for any request if request.method in permissions.SAFE_METHODS: return True # Write permissions only for author return obj.author == request.user class IsOwnerOrAdmin(permissions.BasePermission): def has_object_permission(self, request, view, obj): return obj.owner == request.user or request.user.is_staff # Usage in ViewSet class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer permission_classes = [permissions.IsAuthenticated, IsAuthorOrReadOnly] # Multiple permission classes from rest_framework.permissions import IsAuthenticated, IsAdminUser class AdminPostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer def get_permissions(self): if self.action in ['create', 'update', 'partial_update', 'destroy']: return [IsAdminUser()] return [IsAuthenticated()] ``` ## Authentication Configure various authentication methods. ```python from rest_framework.authentication import TokenAuthentication, SessionAuthentication from rest_framework.authtoken.models import Token from rest_framework.permissions import IsAuthenticated # Token Authentication class PostViewSet(viewsets.ModelViewSet): authentication_classes = [TokenAuthentication] permission_classes = [IsAuthenticated] queryset = Post.objects.all() serializer_class = PostSerializer # Create token for user from rest_framework.authtoken.views import obtain_auth_token from django.urls import path urlpatterns = [ path('api-token-auth/', obtain_auth_token), ] # Custom token authentication from rest_framework.authtoken.views import ObtainAuthToken from rest_framework.authtoken.models import Token from rest_framework.response import Response class CustomAuthToken(ObtainAuthToken): def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] token, created = Token.objects.get_or_create(user=user) return Response({ 'token': token.key, 'user_id': user.pk, 'email': user.email }) # JWT Authentication (using djangorestframework-simplejwt) from rest_framework_simplejwt.authentication import JWTAuthentication class PostViewSet(viewsets.ModelViewSet): authentication_classes = [JWTAuthentication] permission_classes = [IsAuthenticated] ``` ## Filtering and Search Implement advanced filtering capabilities. ```python from django_filters import rest_framework as filters from rest_framework import filters as drf_filters class PostFilter(filters.FilterSet): title = filters.CharFilter(lookup_expr='icontains') 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 = Post fields = ['author', 'published', 'title'] class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer filter_backends = [ filters.DjangoFilterBackend, drf_filters.SearchFilter, drf_filters.OrderingFilter ] filterset_class = PostFilter search_fields = ['title', 'content', 'author__name'] ordering_fields = ['created_at', 'title', 'views'] ordering = ['-created_at'] # Custom filter backend class IsOwnerFilterBackend(filters.BaseFilterBackend): def filter_queryset(self, request, queryset, view): return queryset.filter(owner=request.user) ``` ## Pagination Configure pagination for large datasets. ```python from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination class StandardResultsSetPagination(PageNumberPagination): page_size = 10 page_size_query_param = 'page_size' max_page_size = 100 class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer pagination_class = StandardResultsSetPagination # Cursor pagination for better performance class PostCursorPagination(CursorPagination): page_size = 20 ordering = '-created_at' # Custom pagination class CustomPagination(PageNumberPagination): def get_paginated_response(self, data): return Response({ 'links': { 'next': self.get_next_link(), 'previous': self.get_previous_link() }, 'count': self.page.paginator.count, 'total_pages': self.page.paginator.num_pages, 'results': data }) ``` ## Throttling Rate limit API requests. ```python from rest_framework.throttling import UserRateThrottle, AnonRateThrottle class BurstRateThrottle(UserRateThrottle): rate = '60/min' class SustainedRateThrottle(UserRateThrottle): rate = '1000/day' class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer throttle_classes = [BurstRateThrottle, SustainedRateThrottle] # Custom throttle from rest_framework.throttling import SimpleRateThrottle class UploadRateThrottle(SimpleRateThrottle): rate = '10/hour' def get_cache_key(self, request, view): if request.user.is_authenticated: ident = request.user.pk else: ident = self.get_ident(request) return self.cache_format % {'scope': self.scope, 'ident': ident} ``` ## Versioning Handle API versioning. ```python from rest_framework.versioning import URLPathVersioning, NamespaceVersioning # URL path versioning class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() versioning_class = URLPathVersioning def get_serializer_class(self): if self.request.version == 'v1': return PostSerializerV1 return PostSerializerV2 # URLs urlpatterns = [ path('v1/posts/', PostViewSet.as_view({'get': 'list'})), path('v2/posts/', PostViewSet.as_view({'get': 'list'})), ] # Accept header versioning from rest_framework.versioning import AcceptHeaderVersioning
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기