diff --git a/backend/api/serializers.py b/backend/api/serializers.py index f824b6f..a395d42 100644 --- a/backend/api/serializers.py +++ b/backend/api/serializers.py @@ -385,10 +385,11 @@ class FollowSerializer(serializers.ModelSerializer): username = serializers.StringRelatedField(source='author.username') first_name = serializers.StringRelatedField(source='author.first_name') last_name = serializers.StringRelatedField(source='author.last_name') - recipes = RecipeFollowSerializer(read_only=True, - many=True, source='author.recipe') + # recipes = RecipeFollowSerializer(read_only=True, + # many=True, source='author.recipe') + recipes = serializers.SerializerMethodField() is_subscribed = serializers.SerializerMethodField() - recipes_count = serializers.IntegerField(read_only=True) + recipes_count = serializers.SerializerMethodField() email = serializers.StringRelatedField(source='author.email') class Meta: @@ -416,18 +417,18 @@ def get_is_subscribed(self, obj): return Follow.objects.filter(follower=self.context.get('request').user, author=obj.author).exists() - def to_representation(self, instance): - representation = super().to_representation(instance) - recipes = representation.get('recipes') - print(recipes) - length = len(recipes) - representation['recipes_count'] = length + def get_recipes(self, obj): limit = self.context.get('request').query_params.get('recipes_limit') + recipes = obj.author.recipe.all() if limit: - limit = int(limit) - if length > limit: - representation['recipes'] = recipes[:limit] - return representation + recipes = recipes[:int(limit)] + serializer = RecipeFollowSerializer(recipes, + read_only=True, + many=True) + return serializer.data + + def get_recipes_count(self, obj): + return obj.author.recipe.all().count() def validate(self, attrs): author_id = int(self.context.get( diff --git a/backend/api/utils.py b/backend/api/utils.py index b625b55..b78e451 100644 --- a/backend/api/utils.py +++ b/backend/api/utils.py @@ -14,12 +14,10 @@ class DownloadViewSet(APIView): def merge_shopping_cart(self): """Генерирует список словарей с покупками.""" - shopping_cart = ShoppingCart.objects.filter(user=self.request.user) - recipes = [] - for item in shopping_cart: - recipes.append(item.recipe) + shopping_cart = ShoppingCart.objects.filter( + user=self.request.user).values('recipe') items = RecipeIngredient.objects.filter( - recipe__in=recipes + recipe__in=shopping_cart ).values( 'ingredient__name', 'ingredient__measurement_unit' diff --git a/backend/api/views.py b/backend/api/views.py index 180c969..df0eb88 100644 --- a/backend/api/views.py +++ b/backend/api/views.py @@ -1,5 +1,4 @@ from django.contrib.auth import get_user_model -from django.db.models import Count from django.shortcuts import get_object_or_404 from django_filters.rest_framework import DjangoFilterBackend from rest_framework import mixins, status, viewsets @@ -12,7 +11,6 @@ from core.pagination import CustomPagination from recipes.models import (Favorite, Follow, Ingredient, Recipe, ShoppingCart, Tag) - from .filters import IngredientFilter, RecipeFilter from .permissions import IsOwnerOrReadOnly from .serializers import (FavoriteSerializer, FollowSerializer, @@ -148,7 +146,6 @@ class ShoppingCartViewSet(BaseViewset): class FollowViewSet(BaseViewset): """Вьюсет добавления в Подписки.""" - queryset = Follow.objects.all() serializer_class = FollowSerializer permission_classes = (IsAuthenticated,) http_method_names = ['post', 'delete'] @@ -183,9 +180,9 @@ class FollowListViewSet(mixins.ListModelMixin, pagination_class = CustomPagination def get_queryset(self): - queryset = ( - Follow.objects.annotate(recipes_count=Count('author__recipe'))) - return queryset.filter(follower=self.request.user) + return ( + Follow.objects.filter( + follower=self.request.user).prefetch_related('author__recipe')) class IngredientViewSet(viewsets.ModelViewSet): diff --git a/backend/core/management/commands/test.py b/backend/core/management/commands/test.py index 2119777..7688f51 100644 --- a/backend/core/management/commands/test.py +++ b/backend/core/management/commands/test.py @@ -15,5 +15,3 @@ class Command(BaseCommand): def handle(self, *args, **options): objects = Follow.objects.annotate(count=Count('author__recipe')) for object in objects: - print(object.count) - print(object)