Sử dụng ViewSet và Pagination trong Django REST Framework

Triển khai API với ViewSet trong DRF

Thay vì sử dụng Function-Based Views (FBV), Django REST Framework cung cấp cách tiếp cận Class-Based Views (CBV) để xây dựng API RESTful. Phương pháp này giúp giảm lượng code cần viết và tăng hiệu suất phát triển, mặc dù có thể kém linh hoạt hơn so với FBV.

Kế thừa từ APIView

DRF cung cấp các lớp con của APIView cho các thao tác CRUD cơ bản:

  • ListAPIView - xử lý GET request để lấy danh sách
  • CreateAPIView - xử lý POST request để tạo mới
  • UpdateAPIView - xử lý PUT/PATCH request để cập nhật
  • DestroyAPIView - xử lý DELETE request để xóa
from rest_framework.generics import ListAPIView
from .models import Course
from .serializers import CourseSerializer

class CourseListView(ListAPIView):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

Cấu hình URL cho view class:

from django.urls import path
from .views import CourseListView

urlpatterns = [
    path('api/courses/', CourseListView.as_view()),
]

Sử dụng ModelViewSet

Để triển khai đầy đủ các thao tác CRUD với ít code nhất, có thể sử dụng ModelViewSet:

from rest_framework.viewsets import ModelViewSet
from .models import Course
from .serializers import CourseSerializer

class CourseViewSet(ModelViewSet):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer

ModelViewSet kế thừa từ nhiều mixin classes, cung cấp các phương thức:

  • create() - POST request
  • retrieve() - GET request (chi tiết)
  • update() - PUT/PATCH request
  • destroy() - DELETE request
  • list() - GET request (danh sách)

Đăng ký ViewSet với router:

from rest_framework.routers import DefaultRouter
from .views import CourseViewSet

router = DefaultRouter()
router.register('api/courses', CourseViewSet)
urlpatterns += router.urls

DRF cũng cung cấp ReadOnlyModelViewSet cho các API chỉ cho phép đọc dữ liệu.

Phân trang dữ liệu

Để phân trang dữ liệu trong DRF, cấu hình trong settings.py:

REST_FRAMEWORK = {
    'PAGE_SIZE': 10,
    'DEFAULT_PAGINATION_CLASS': 
        'rest_framework.pagination.PageNumberPagination'
}

Ngoài PageNumberPagination, DRF còn cung cấp:

  • LimitOffsetPagination - phân trang dựa trên limit/offset
  • CursorPagination - phân trang sử dụng cursor, bảo mật hơn

Tùy chỉnh phân trang với class riêng:

from rest_framework.pagination import PageNumberPagination

class CustomPagination(PageNumberPagination):
    page_size = 8
    page_size_query_param = 'limit'
    max_page_size = 100

class CourseListView(ListAPIView):
    queryset = Course.objects.all()
    serializer_class = CourseSerializer
    pagination_class = CustomPagination

Để tắt phân trang, đặt pagination_class = None.

Lọc dữ liệu

Để lọc dữ liệu dựa trên tham số request, ghi đè phương thức get_queryset:

class InstructorView(ListAPIView):
    serializer_class = InstructorSerializer

    def get_queryset(self):
        queryset = Instructor.objects.all()
        department_id = self.request.GET.get('dept', '')
        if department_id:
            queryset = queryset.filter(department_id=department_id)
        return queryset

Ngoài ra có thể sử dụng thư viện django-filter để lọc dữ liệu với cấu hình đơn giản hơn.

Thẻ: Django DRF ViewSet pagination API

Đăng vào ngày 12 tháng 8 lúc 13:04