Last active
May 19, 2026 07:54
-
-
Save sunmeat/6ef70de4764562964abcf517d0cb8e05 to your computer and use it in GitHub Desktop.
ViewSets + Routers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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