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áchCreateAPIView- xử lý POST request để tạo mớiUpdateAPIView- xử lý PUT/PATCH request để cập nhậtDestroyAPIView- 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 requestretrieve()- GET request (chi tiết)update()- PUT/PATCH requestdestroy()- DELETE requestlist()- 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/offsetCursorPagination- 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.