Rest Framework
Views

Django Rest Framework Views - Panduan Lengkap

1. Function Based Views

Dasar API View

# views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
 
@api_view(['GET', 'POST'])
def product_list(request):
    if request.method == 'GET':
        products = Product.objects.all()
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data)
 
    elif request.method == 'POST':
        serializer = ProductSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)

API View dengan Detail

@api_view(['GET', 'PUT', 'DELETE'])
def product_detail(request, pk):
    try:
        product = Product.objects.get(pk=pk)
    except Product.DoesNotExist:
        return Response(status=404)
 
    if request.method == 'GET':
        serializer = ProductSerializer(product)
        return Response(serializer.data)
 
    elif request.method == 'PUT':
        serializer = ProductSerializer(product, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=400)
 
    elif request.method == 'DELETE':
        product.delete()
        return Response(status=204)

2. Class Based Views

Generic API Views

from rest_framework import generics
 
class ProductList(generics.ListCreateAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
 
class ProductDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

ViewSet

from rest_framework import viewsets
 
class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

3. Permissions

Penggunaan Permission

from rest_framework.permissions import IsAuthenticated, IsAdminUser
 
class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    permission_classes = [IsAuthenticated]

Custom Permission

from rest_framework import permissions
 
class IsOwnerOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True
        return obj.owner == request.user

4. Filtering dan Searching

Filter Backend

from rest_framework import filters
 
class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['name', 'description']
    ordering_fields = ['price', 'created_at']

Custom Filtering

class ProductViewSet(viewsets.ModelViewSet):
    serializer_class = ProductSerializer
 
    def get_queryset(self):
        queryset = Product.objects.all()
        category = self.request.query_params.get('category', None)
        if category is not None:
            queryset = queryset.filter(category=category)
        return queryset

5. Pagination

Setting Pagination

from rest_framework.pagination import PageNumberPagination
 
class StandardResultsSetPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100
 
class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    pagination_class = StandardResultsSetPagination

6. Authentication

Token Authentication

from rest_framework.authtoken.views import obtain_auth_token
from rest_framework.authentication import TokenAuthentication
 
# urls.py
urlpatterns = [
    path('api-token-auth/', obtain_auth_token),
]
 
# views.py
class ProductViewSet(viewsets.ModelViewSet):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]

7. Tips dan Trik

Overriding Methods

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
 
    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)
 
    def get_serializer_context(self):
        context = super().get_serializer_context()
        context['user'] = self.request.user
        return context

Custom Actions

from rest_framework.decorators import action
 
class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
 
    @action(detail=True, methods=['post'])
    def mark_featured(self, request, pk=None):
        product = self.get_object()
        product.is_featured = True
        product.save()
        return Response({'status': 'produk ditandai sebagai unggulan'})

Error Handling

from rest_framework.exceptions import ValidationError
 
class ProductViewSet(viewsets.ModelViewSet):
    def create(self, request, *args, **kwargs):
        try:
            return super().create(request, *args, **kwargs)
        except ValidationError as e:
            return Response({
                'error': 'Terjadi kesalahan validasi',
                'details': str(e)
            }, status=400)