class BookDetailView(APIView):
def get_object(self, pk):
"""Вспомогательный метод — DRY"""
try:
return Book.objects.get(pk=pk)
except Book.DoesNotExist:
return None
def get(self, request, pk):
book = self.get_object(pk)
if book is None:
return Response({'error': 'Not found'},
status=status.HTTP_404_NOT_FOUND)
...
def put(self, request, pk):
book = self.get_object(pk)
if book is None:
return Response({'error': 'Not found'},
status=status.HTTP_404_NOT_FOUND)
...
from rest_framework import status
return Response(data, status=status.HTTP_201_CREATED)
return Response(error, status=status.HTTP_400_BAD_REQUEST)
return Response(status=status.HTTP_204_NO_CONTENT)
# Явно, читаемо, без «магических чисел»
3. PATCH без partial=True
Из лекции (старое)
Современный подход
# Лекция показывает только PUT
# PATCH не рассматривается отдельно
def put(self, request, pk):
serializer = BookSerializer(book, data=request.data)
...
# Много boilerplate кода
class BookListCreateView(APIView):
def get(self, request):
books = Book.objects.all()
s = BookSerializer(books, many=True)
return Response(s.data)
def post(self, request):
s = BookSerializer(data=request.data)
if s.is_valid():
s.save()
return Response(s.data, status=201)
return Response(s.errors, status=400)
# Минимум кода — то же поведение
from rest_framework import generics
class BookListCreateView(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# Готово. DRF реализует get() и post() автоматически.
Используйте APIView, когда нужна нестандартная логика. Для стандартного CRUD — Generic Views или ViewSet.
class BookListCreateView(APIView):
def get(self, request):
# select_related — для ForeignKey (publisher)
# prefetch_related — для ManyToMany (genres)
books = Book.objects.select_related('publisher')\
.prefetch_related('genres')\
.all()
serializer = BookSerializer(books, many=True)
return Response(serializer.data)
⚠️ Проверить по документации: DRF 3.15+ добавил улучшения в работе с nested serializers и throttling. Для актуальных примеров pagination_class, filter_backends и permission_classes см. официальную документацию DRF 3.15+.