# # backend/api/views.py # from rest_framework import generics, viewsets, permissions, status # from django.contrib.auth import get_user_model # from rest_framework_simplejwt.views import TokenObtainPairView # from rest_framework.views import APIView # from rest_framework.response import Response # from django.shortcuts import get_object_or_404 # from drf_spectacular.utils import extend_schema, OpenApiParameter # from .models import Link, LinkGroup # from .serializers import ( # RegisterSerializer, # UserSerializer, # LinkSerializer, # LinkGroupSerializer, # ) # User = get_user_model() # @extend_schema( # parameters=[ # OpenApiParameter( # name='id', # type=int, # location=OpenApiParameter.PATH # ) # ] # ) # class RegisterView(generics.CreateAPIView): # """ # POST /api/auth/register/ # Регистрирует нового пользователя. # """ # queryset = User.objects.all() # permission_classes = (permissions.AllowAny,) # serializer_class = RegisterSerializer # class LoginView(TokenObtainPairView): # """ # POST /api/auth/login/ # Возвращает JWT-токены. # """ # permission_classes = (permissions.AllowAny,) # class LinkGroupViewSet(viewsets.ModelViewSet): # """ # /api/groups/ # CRUD для групп ссылок текущего пользователя. # """ # queryset = LinkGroup.objects.all() # serializer_class = LinkGroupSerializer # permission_classes = [permissions.IsAuthenticated] # def get_queryset(self): # # Возвращаем только свои группы, упорядоченные по полю order # return self.queryset.filter(owner=self.request.user).order_by('order') # def perform_create(self, serializer): # # При создании модели автоматически ставим owner = текущий пользователь # serializer.save(owner=self.request.user) # class LinkViewSet(viewsets.ModelViewSet): # """ # /api/links/ # CRUD для ссылок текущего пользователя. # """ # serializer_class = LinkSerializer # permission_classes = (permissions.IsAuthenticated,) # def get_queryset(self): # # Возвращаем только свои ссылки, упорядоченные по полю order # return Link.objects.filter(owner=self.request.user).order_by('order') # def perform_create(self, serializer): # # При создании модели автоматически ставим owner = текущий пользователь # serializer.save(owner=self.request.user) # class UserLinksListView(generics.ListAPIView): # """ # GET /api/users/{username}/links/ # Список публичных ссылок пользователя (без группировки). # """ # serializer_class = LinkSerializer # permission_classes = (permissions.AllowAny,) # def get_queryset(self): # username = self.kwargs['username'] # return Link.objects.filter(owner__username=username).order_by('order') # class UserProfileView(generics.RetrieveAPIView): # """ # GET /api/auth/user/ # Возвращает данные авторизованного пользователя. # """ # serializer_class = UserSerializer # permission_classes = [permissions.IsAuthenticated] # def get_object(self): # return self.request.user # class PublicUserGroupsView(APIView): # """ # GET /api/users/{username}/public/ # Возвращает публичные группы и ссылки пользователя. # """ # permission_classes = [permissions.AllowAny] # def get(self, request, username): # user = get_object_or_404(User, username=username) # # Берем все группы пользователя вместе с их ссылками # groups_qs = LinkGroup.objects.filter(owner=user).prefetch_related('links') # result = { # "username": user.username, # "groups": [] # } # for grp in groups_qs: # # URL иконки группы (поле icon в модели) # grp_icon_url = grp.icon.url if grp.icon else None # grp_data = { # "id": grp.id, # "name": grp.name, # "icon": grp_icon_url, # "links": [], # } # for ln in grp.links.all(): # # URL иконки ссылки (поле icon в модели Link — URLField) # link_icon_url = ln.icon if ln.icon else None # grp_data["links"].append({ # "id": ln.id, # "title": ln.title, # "url": ln.url, # "icon": link_icon_url, # }) # result["groups"].append(grp_data) # return Response(result, status=status.HTTP_200_OK) # backend/api/views.py from rest_framework import generics, viewsets, permissions, status from rest_framework.parsers import MultiPartParser, FormParser, JSONParser from rest_framework_simplejwt.views import TokenObtainPairView from rest_framework.views import APIView from rest_framework.response import Response from django.shortcuts import get_object_or_404 from drf_spectacular.utils import extend_schema, OpenApiParameter from django.contrib.auth import get_user_model from .models import Link, LinkGroup from .serializers import ( RegisterSerializer, UserSerializer, LinkSerializer, LinkGroupSerializer, ) User = get_user_model() class RegisterView(generics.CreateAPIView): queryset = User.objects.all() permission_classes = [permissions.AllowAny] serializer_class = RegisterSerializer class LoginView(TokenObtainPairView): permission_classes = [permissions.AllowAny] class LinkGroupViewSet(viewsets.ModelViewSet): queryset = LinkGroup.objects.all() serializer_class = LinkGroupSerializer permission_classes = [permissions.IsAuthenticated] parser_classes = [MultiPartParser, FormParser, JSONParser] def get_queryset(self): return self.queryset.filter(owner=self.request.user).order_by('order') def perform_create(self, serializer): serializer.save(owner=self.request.user) class LinkViewSet(viewsets.ModelViewSet): queryset = Link.objects.all() serializer_class = LinkSerializer permission_classes = [permissions.IsAuthenticated] parser_classes = [MultiPartParser, FormParser, JSONParser] def get_queryset(self): return Link.objects.filter(owner=self.request.user).order_by('order') def perform_create(self, serializer): serializer.save(owner=self.request.user) class UserProfileView(generics.RetrieveAPIView): serializer_class = UserSerializer permission_classes = [permissions.IsAuthenticated] def get_object(self): return self.request.user class UserLinksListView(generics.ListAPIView): serializer_class = LinkSerializer permission_classes = [permissions.AllowAny] def get_queryset(self): username = self.kwargs['username'] return Link.objects.filter(owner__username=username).order_by('order') class PublicUserGroupsView(APIView): """ GET /api/users/{username}/public/ """ permission_classes = [permissions.AllowAny] def get(self, request, username): user = get_object_or_404(User, username=username) # Берём все группы пользователя вместе с их ссылками groups_qs = LinkGroup.objects.filter(owner=user).prefetch_related('links') result = { "username": user.username, "groups": [] } for grp in groups_qs: # поле icon у группы — это ImageField grp_icon_url = grp.icon.url if grp.icon else None grp_data = { "id": grp.id, "name": grp.name, "image": grp_icon_url, # отдаём под ключом "image", как ждёт фронт "links": [], } for ln in grp.links.all(): # поле icon у ссылки — это URLField, сразу строка link_icon_url = ln.icon if ln.icon else None grp_data["links"].append({ "id": ln.id, "title": ln.title, "url": ln.url, "image": link_icon_url, # тоже "image" }) result["groups"].append(grp_data) return Response(result, status=status.HTTP_200_OK)