Напиши в одном стиле код ниже class UserViewSet(vi...

Criado em: 16 de fevereiro de 2025

Respondido usando O1 por Chat01

Pergunta

Напиши в одном стиле код ниже
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = EditUserSerializer
pagination_class = CustomPagination

text
def get_serializer_class(self): if self.action in ('list', 'retrieve'): return EditUserSerializer return RegistrationUserSerializer @action(detail=False, methods=['get'], permission_classes=(IsAuthenticated,)) def me(self, request): serializer = EditUserSerializer(request.user, context={'request': request}) return Response(serializer.data, status=status.HTTP_200_OK) @action(detail=False, methods=['post'], permission_classes=[IsAuthenticated]) def set_password(self, request, *args, **kwargs): serializer = SetPasswordSerializer( data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) self.request.user.set_password(serializer.data['new_password']) self.request.user.save() return Response('Пароль изменен', status=status.HTTP_204_NO_CONTENT) @action( detail=True, methods=['post', 'delete'], permission_classes=[IsAuthenticated] ) def subscribe(self, request, pk=None): """ Подписка/отписка на автора с id=kwargs['id']. """ user = request.user author = get_object_or_404(User, pk=pk) limit_param = request.query_params.get('recipes_limit') if request.method == 'POST': if user == author: return Response( {'errors': 'Нельзя подписаться на самого себя.'}, status=status.HTTP_400_BAD_REQUEST ) follow, created = Follow.objects.get_or_create( user=user, author=author ) if not created: return Response( {'errors': 'Вы уже подписаны на этого автора.'}, status=status.HTTP_400_BAD_REQUEST ) serializer = FollowListSerializer( author, context={'request': request, 'limit_param': limit_param} ) return Response(serializer.data, status=status.HTTP_201_CREATED) if request.method == 'DELETE': follow = Follow.objects.filter(user=user, author=author).first() if not follow: return Response( {'errors': 'Подписка не найдена.'}, status=status.HTTP_400_BAD_REQUEST ) follow.delete() return Response(status=status.HTTP_204_NO_CONTENT) @action( detail=False, permission_classes=[IsAuthenticated] ) def subscriptions(self, request): ''' GET /users/subscriptions/ Список авторов, на которых подписан текущий пользователь. ''' users = User.objects.filter(author__user=request.user) paginated_queryset = self.paginate_queryset(users) if paginated_queryset is not None: serializer = FollowListSerializer( paginated_queryset, many=True, context={'request': request} ) return self.get_paginated_response(serializer.data) serializer = FollowListSerializer(paginated_queryset, many=True, context={'request': request}) return Response(serializer.data) @action( detail=True, methods=['put', 'delete'], permission_classes=[IsAuthenticated]) def avatar(self, request, **kwargs): user = get_object_or_404(User, pk=request.user.id) if request.method == 'PUT': serializers = EditUserSerializer( user, data=request.data, partial=True, context={'request': request} ) serializers.is_valid(raise_exception=True) serializers.save() return Response({'avatar': serializers.data.get('avatar')}, status=HTTP_200_OK) user.avatar = None user.save() return Response(status=status.HTTP_204_NO_CONTENT)

class RecipeViewSet(viewsets.ModelViewSet):
queryset = Recipe.objects.all()
serializer_class = CreateRecipeSerializer
permission_classes = [IsOwnerOrAdmin]
filter_backends = (DjangoFilterBackend,)
filterset_class = TagAuthorFilter
pagination_class = CustomPagination

text
def get_serializer_class(self): """Выбираем сериалайзер""" if self.action in ('list', 'retrieve'): return RecipeSerializer return CreateRecipeSerializer def get_permissions(self): """Разные разрешения для разных экшенов.""" if self.action in ('shopping_cart',): return [IsAuthenticated()] return super().get_permissions() @action(detail=True, permission_classes=(AllowAny,), url_path='get-link') def get_short_link(self, request, **kwargs): """ Генерирует или получает из базы короткую ссылку для рецепта. """ recipe = get_object_or_404(Recipe, id=kwargs['pk']) if not recipe.short_link: while True: short_code = generate_short_code(3) if not Recipe.objects.filter(short_link=short_code).exists(): recipe.short_link = short_code recipe.save() break return Response( {'short-link': recipe.short_link}, status=status.HTTP_200_OK ) @action(detail=True, methods=['post', 'delete'], url_path='shopping_cart') def shopping_cart(self, request, pk): """Добавляет/удаляет рецепт в список покупок пользователя.""" user = request.user recipe = get_object_or_404(Recipe, pk=pk) if request.method == 'POST': if ShoppingCart.objects.filter(user=user, recipe=recipe).exists(): return Response( {'errors': 'Рецепт уже в списке покупок.'}, status=status.HTTP_400_BAD_REQUEST ) ShoppingCart.objects.create(user=user, recipe=recipe) serializer = ListRecipeUsersSerializer( recipe, context={'request': request}) return Response(serializer.data, status=status.HTTP_201_CREATED) if request.method == 'DELETE': in_cart = ShoppingCart.objects.filter(user=user, recipe=recipe) if not in_cart: return Response( {"detail": "Рецепт не найден в списке покупок."}, status=status.HTTP_400_BAD_REQUEST ) in_cart.delete() return Response( {'detail': 'Рецепт успешно удален из списке покупок.'}, status=status.HTTP_204_NO_CONTENT) @action(detail=False, methods=['get'], permission_classes=[IsAuthenticated]) def download_shopping_cart(self, request, **kwargs): ingredients = ( IngredientRecipe.objects .filter(recipe__shoppingcart_recipes__user=request.user) .values('ingredient') .annotate(total_amount=Sum('amount')) .values_list('ingredient__name', 'total_amount', 'ingredient__measurement_unit') ) lines = [] for name, total, unit in ingredients: lines.append(f'{name} - {total} {unit}') shopping_list = "\n".join(lines) or "Список для покупок пуст." response = HttpResponse(shopping_list, content_type='text/plain') response['Content-Disposition'] = 'attachment; \ filename="shopping_list.txt"' return response @action( detail=True, methods=['post', 'delete'], permission_classes=[IsAuthenticated], url_path='favorite') def favorite(self, request, pk): recipe = get_object_or_404(Recipe, pk=pk) if request.method == 'POST': if Favorite.objects.filter(user=request.user, recipe=recipe).exists(): return Response({'errors': 'Рецепт уже в избранном.'}, status=status.HTTP_400_BAD_REQUEST) Favorite.objects.create(user=request.user, recipe=recipe) serializer = ListRecipeUsersSerializer( recipe, context={'request': request} ) return Response(serializer.data, status=status.HTTP_201_CREATED) if request.method == 'DELETE': favorite = Favorite.objects.filter( user=request.user, recipe=recipe ).first() if not favorite: return Response( {'errors': 'Рецепт не найден в избранном.'}, status=status.HTTP_400_BAD_REQUEST ) favorite.delete() return Response( {'detail': 'Рецепт успешно удален из избранного.'}, status=status.HTTP_204_NO_CONTENT )

Pensamento

Aligning docstring style

Standardizing docstrings

I’m thinking about unifying docstrings to either single-line or multiline formats, ensuring all functions have them, and possibly placing them after the function signature.

Synthesizing docstrings

I'm combining all docstrings into a consistent format with triple quotes, ensuring each function has a well-defined docstring style to improve clarity and maintainability.

Enhancing clarity

I’m thinking through standardizing docstrings to multiline triple quotes for consistency, addressing formatting, and ensuring precise terminology to enhance code readability and comprehension.

Unifying docstring style

I’m focusing on aligning docstring formatting to triple quotes for consistency, ensuring comprehensive and readable documentation across all methods, and maintaining code clarity.

Reasoned for 11 seconds

Resposta

python
from django.contrib.auth import get_user_model from django.db.models import Sum from django.http import HttpResponse from django.shortcuts import get_object_or_404 from django_filters.rest_framework import DjangoFilterBackend from rest_framework import status, viewsets from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.response import Response from rest_framework.status import HTTP_200_OK from .filters import TagAuthorFilter from .models import ( Follow, Favorite, IngredientRecipe, Recipe, ShoppingCart ) from .pagination import CustomPagination from .permissions import IsOwnerOrAdmin from .serializers import ( CreateRecipeSerializer, EditUserSerializer, FollowListSerializer, ListRecipeUsersSerializer, RegistrationUserSerializer, SetPasswordSerializer, RecipeSerializer ) from .utils import generate_short_code User = get_user_model() class UserViewSet(viewsets.ModelViewSet): """ Вьюсет для управления пользователями. """ queryset = User.objects.all() serializer_class = EditUserSerializer pagination_class = CustomPagination def get_serializer_class(self): """ Возвращает сериализатор в зависимости от действия (action). """ if self.action in ('list', 'retrieve'): return EditUserSerializer return RegistrationUserSerializer @action(detail=False, methods=['get'], permission_classes=(IsAuthenticated,)) def me(self, request): """ Возвращает данные текущего пользователя. """ serializer = EditUserSerializer(request.user, context={'request': request}) return Response(serializer.data, status=status.HTTP_200_OK) @action( detail=False, methods=['post'], permission_classes=[IsAuthenticated] ) def set_password(self, request, *args, **kwargs): """ Изменяет пароль текущего пользователя. """ serializer = SetPasswordSerializer(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) request.user.set_password(serializer.data['new_password']) request.user.save() return Response('Пароль изменен', status=status.HTTP_204_NO_CONTENT) @action( detail=True, methods=['post', 'delete'], permission_classes=[IsAuthenticated] ) def subscribe(self, request, pk=None): """ Подписка или отписка от автора с id=pk. """ user = request.user author = get_object_or_404(User, pk=pk) limit_param = request.query_params.get('recipes_limit') if request.method == 'POST': if user == author: return Response( {'errors': 'Нельзя подписаться на самого себя.'}, status=status.HTTP_400_BAD_REQUEST ) follow, created = Follow.objects.get_or_create(user=user, author=author) if not created: return Response( {'errors': 'Вы уже подписаны на этого автора.'}, status=status.HTTP_400_BAD_REQUEST ) serializer = FollowListSerializer( author, context={'request': request, 'limit_param': limit_param} ) return Response(serializer.data, status=status.HTTP_201_CREATED) if request.method == 'DELETE': follow = Follow.objects.filter(user=user, author=author).first() if not follow: return Response( {'errors': 'Подписка не найдена.'}, status=status.HTTP_400_BAD_REQUEST ) follow.delete() return Response(status=status.HTTP_204_NO_CONTENT) @action( detail=False, permission_classes=[IsAuthenticated] ) def subscriptions(self, request): """ GET /users/subscriptions/ Возвращает список авторов, на которых подписан текущий пользователь. """ users = User.objects.filter(author__user=request.user) paginated_queryset = self.paginate_queryset(users) if paginated_queryset is not None: serializer = FollowListSerializer( paginated_queryset, many=True, context={'request': request} ) return self.get_paginated_response(serializer.data) serializer = FollowListSerializer(paginated_queryset, many=True, context={'request': request}) return Response(serializer.data) @action( detail=True, methods=['put', 'delete'], permission_classes=[IsAuthenticated] ) def avatar(self, request, **kwargs): """ Обновляет или удаляет аватар текущего пользователя. """ user = get_object_or_404(User, pk=request.user.id) if request.method == 'PUT': serializers = EditUserSerializer( user, data=request.data, partial=True, context={'request': request} ) serializers.is_valid(raise_exception=True) serializers.save() return Response( {'avatar': serializers.data.get('avatar')}, status=HTTP_200_OK ) user.avatar = None user.save() return Response(status=status.HTTP_204_NO_CONTENT) class RecipeViewSet(viewsets.ModelViewSet): """ Вьюсет для управления рецептами. """ queryset = Recipe.objects.all() serializer_class = CreateRecipeSerializer permission_classes = [IsOwnerOrAdmin] filter_backends = (DjangoFilterBackend,) filterset_class = TagAuthorFilter pagination_class = CustomPagination def get_serializer_class(self): """ Возвращает сериализатор в зависимости от действия (action). """ if self.action in ('list', 'retrieve'): return RecipeSerializer return CreateRecipeSerializer def get_permissions(self): """ Разные разрешения для разных экшенов. """ if self.action in ('shopping_cart',): return [IsAuthenticated()] return super().get_permissions() @action(detail=True, permission_classes=(AllowAny,), url_path='get-link') def get_short_link(self, request, **kwargs): """ Генерирует или получает из базы короткую ссылку для рецепта. """ recipe = get_object_or_404(Recipe, id=kwargs['pk']) if not recipe.short_link: while True: short_code = generate_short_code(3) if not Recipe.objects.filter(short_link=short_code).exists(): recipe.short_link = short_code recipe.save() break return Response({'short-link': recipe.short_link}, status=status.HTTP_200_OK) @action( detail=True, methods=['post', 'delete'], url_path='shopping_cart' ) def shopping_cart(self, request, pk): """ Добавляет или удаляет рецепт в списке покупок текущего пользователя. """ user = request.user recipe = get_object_or_404(Recipe, pk=pk) if request.method == 'POST': if ShoppingCart.objects.filter(user=user, recipe=recipe).exists(): return Response( {'errors': 'Рецепт уже в списке покупок.'}, status=status.HTTP_400_BAD_REQUEST ) ShoppingCart.objects.create(user=user, recipe=recipe) serializer = ListRecipeUsersSerializer(recipe, context={'request': request}) return Response(serializer.data, status=status.HTTP_201_CREATED) if request.method == 'DELETE': in_cart = ShoppingCart.objects.filter(user=user, recipe=recipe) if not in_cart: return Response( {'detail': 'Рецепт не найден в списке покупок.'}, status=status.HTTP_400_BAD_REQUEST ) in_cart.delete() return Response( {'detail': 'Рецепт успешно удален из списка покупок.'}, status=status.HTTP_204_NO_CONTENT ) @action( detail=False, methods=['get'], permission_classes=[IsAuthenticated] ) def download_shopping_cart(self, request, **kwargs): """ Позволяет скачать список покупок текущего пользователя. """ ingredients = ( IngredientRecipe.objects .filter(recipe__shoppingcart_recipes__user=request.user) .values('ingredient') .annotate(total_amount=Sum('amount')) .values_list('ingredient__name', 'total_amount', 'ingredient__measurement_unit') ) lines = [] for name, total, unit in ingredients: lines.append(f'{name} - {total} {unit}') shopping_list = '\n'.join(lines) or 'Список для покупок пуст.' response = HttpResponse(shopping_list, content_type='text/plain') response['Content-Disposition'] = 'attachment; filename="shopping_list.txt"' return response @action( detail=True, methods=['post', 'delete'], permission_classes=[IsAuthenticated], url_path='favorite' ) def favorite(self, request, pk): """ Добавляет или удаляет рецепт из избранного текущего пользователя. """ recipe = get_object_or_404(Recipe, pk=pk) if request.method == 'POST': if Favorite.objects.filter(user=request.user, recipe=recipe).exists(): return Response( {'errors': 'Рецепт уже в избранном.'}, status=status.HTTP_400_BAD_REQUEST ) Favorite.objects.create(user=request.user, recipe=recipe) serializer = ListRecipeUsersSerializer(recipe, context={'request': request}) return Response(serializer.data, status=status.HTTP_201_CREATED) if request.method == 'DELETE': favorite = Favorite.objects.filter(user=request.user, recipe=recipe).first() if not favorite: return Response( {'errors': 'Рецепт не найден в избранном.'}, status=status.HTTP_400_BAD_REQUEST ) favorite.delete() return Response( {'detail': 'Рецепт успешно удален из избранного.'}, status=status.HTTP_204_NO_CONTENT )

В приведённом коде все методы и их описания оформлены в едином стиле:

  1. Класс-докстринги: В начале каждого вьюсета есть общий docstring, описывающий назначение класса.
  2. Метод-докстринги: Для каждого метода используется многострочный docstring в тройных кавычках """ ... """.
  3. Структура и отступы: Используется 4 пробела в качестве отступа, методы отделяются пустыми строками, аннотации типов не добавлены (как и в исходном примере).
  4. Оформление docstrings: Все docstrings приведены к единому виду (многострочному).

Таким образом, код выглядит единообразно и соответствует базовым рекомендациям по оформлению.

Compartilhar esta Q&A