Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active May 19, 2026 07:54
Show Gist options
  • Select an option

  • Save sunmeat/6ef70de4764562964abcf517d0cb8e05 to your computer and use it in GitHub Desktop.

Select an option

Save sunmeat/6ef70de4764562964abcf517d0cb8e05 to your computer and use it in GitHub Desktop.
ViewSets + Routers
api / views.py:
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAdminUser
from .models import Artist, Album, Track, Genre
from .serializers import (
ArtistSerializer,
AlbumReadSerializer,
AlbumWriteSerializer,
TrackReadSerializer,
TrackWriteSerializer,
GenreSerializer,
)
# =========================
# ModelViewSet - це клас, який надає стандартні дії для роботи з моделями (list, create, retrieve, update, destroy) без необхідності писати код для кожної дії окремо
# =========================
class ArtistViewSet(ModelViewSet):
queryset = Artist.objects.all()
serializer_class = ArtistSerializer
permission_classes = [AllowAny] # дозволяє всім користувачам отримувати доступ до цього ViewSet (для GET-запитів), але для POST/PUT/PATCH/DELETE буде потрібна авторизація (IsAdminUser - тільки для адміністраторів)
# =========================
# альбом
# =========================
class AlbumViewSet(ModelViewSet):
queryset = Album.objects.select_related('artist').prefetch_related('genres')
# select_related - це оптимізація для ForeignKey, яка виконує JOIN і отримує пов'язані об'єкти в одному запиті
# prefetch_related - це оптимізація для ManyToManyField, яка виконує окремий запит для отримання пов'язаних об'єктів і кешує їх для подальшого використання
def get_serializer_class(self): # цей метод дозволяє вибрати різні серіалізатори для різних дій (наприклад, для list і retrieve використовувати один серіалізатор, а для create і update - інший)
if self.action in ['list', 'retrieve']:
return AlbumReadSerializer
return AlbumWriteSerializer
# =========================
# трек
# =========================
class TrackViewSet(ModelViewSet):
queryset = Track.objects.select_related('album').prefetch_related('artists', 'genres')
def get_serializer_class(self):
if self.action in ['list', 'retrieve']:
return TrackReadSerializer
return TrackWriteSerializer
# =========================
# жанр
# =========================
class GenreViewSet(ModelViewSet):
queryset = Genre.objects.all()
serializer_class = GenreSerializer
========================================================================================
api / urls.py:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import (
ArtistViewSet,
AlbumViewSet,
TrackViewSet,
GenreViewSet,
)
router = DefaultRouter()
router.register(r'artists', ArtistViewSet, basename='artist')
router.register(r'albums', AlbumViewSet, basename='album')
router.register(r'tracks', TrackViewSet, basename='track')
router.register(r'genres', GenreViewSet, basename='genre')
urlpatterns = [
path('', include(router.urls)),
]
# що автоматично створилось:
# Artists:
# GET /api/v1/artists/
# POST /api/v1/artists/
# GET /api/v1/artists/{id}/
# PUT /api/v1/artists/{id}/
# PATCH /api/v1/artists/{id}/
# DELETE /api/v1/artists/{id}/
# Albums / Tracks / Genres — так само
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment