From cedc543e9408dea0729e7cc2a7b9efd3bf7e44a5 Mon Sep 17 00:00:00 2001 From: Sergey Mazilin Date: Sat, 11 Nov 2023 12:42:21 +0400 Subject: [PATCH] =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D0=B6=D0=BD=D1=8B=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8F?= =?UTF-8?q?=20=D0=B8=D0=B7=20Recipes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +++- backend/api/filters.py | 2 +- backend/api/permissions.py | 2 +- backend/api/serializers.py | 20 ++++++------- backend/api/urls.py | 11 +++----- backend/api/utils.py | 6 ++-- backend/api/views.py | 21 +++++++------- backend/core/management/commands/import.py | 3 +- backend/core/management/commands/test.py | 1 - backend/core/pagination.py | 2 +- backend/foodgram/urls.py | 2 +- backend/recipes/admin.py | 22 ++++----------- backend/recipes/migrations/0001_initial.py | 3 +- .../migrations/0005_recipe_pub_date.py | 2 +- .../migrations/0007_auto_20231111_0536.py | 1 + .../migrations/0008_auto_20231111_1154.py | 28 +++++++++++++++++++ backend/recipes/models.py | 8 +----- backend/users/admin.py | 2 +- backend/users/migrations/0001_initial.py | 2 +- 19 files changed, 77 insertions(+), 66 deletions(-) create mode 100644 backend/recipes/migrations/0008_auto_20231111_1154.py diff --git a/.gitignore b/.gitignore index 68d02c1..459c840 100644 --- a/.gitignore +++ b/.gitignore @@ -168,4 +168,7 @@ static/ frontend/ # vscode -.vscode/ \ No newline at end of file +.vscode/ +/.vscode +/.vscode/ +.vscode \ No newline at end of file diff --git a/backend/api/filters.py b/backend/api/filters.py index 272d584..2e1cf23 100644 --- a/backend/api/filters.py +++ b/backend/api/filters.py @@ -1,7 +1,7 @@ import django_filters from django_filters.widgets import BooleanWidget -from recipes.models import Recipe, Ingredient +from recipes.models import Ingredient, Recipe class RecipeFilter(django_filters.FilterSet): diff --git a/backend/api/permissions.py b/backend/api/permissions.py index 68e118e..4371172 100644 --- a/backend/api/permissions.py +++ b/backend/api/permissions.py @@ -1,4 +1,4 @@ -from rest_framework.permissions import BasePermission, SAFE_METHODS +from rest_framework.permissions import SAFE_METHODS, BasePermission class IsOwnerOrReadOnly(BasePermission): diff --git a/backend/api/serializers.py b/backend/api/serializers.py index 591dded..8d9c44c 100644 --- a/backend/api/serializers.py +++ b/backend/api/serializers.py @@ -1,15 +1,15 @@ -import re import base64 +import re + +from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.hashers import make_password from django.core.files.base import ContentFile from rest_framework import serializers from rest_framework.validators import UniqueValidator -from django.conf import settings - -from recipes.models import (Tag, Recipe, RecipeIngredient, Ingredient, - Favorite, ShoppingCart, Follow,) +from recipes.models import (Favorite, Follow, Ingredient, Recipe, + RecipeIngredient, ShoppingCart, Tag) User = get_user_model() @@ -318,9 +318,6 @@ def create(self, validated_data): def update(self, instance, validated_data): items = validated_data.pop('recipeingredient') - # if not items: - # raise serializers.ValidationError( - # 'Ингредиенты не могут быть пустыми') RecipeIngredient.objects.filter(recipe=instance).delete() instance = super().update(instance, validated_data) self.create_ingredient(items, instance) @@ -416,14 +413,13 @@ class Meta: model = Follow def get_is_subscribed(self, obj): - if Follow.objects.filter(follower=self.context.get('request').user, - author=obj.author).exists(): - return True - return False + 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 limit = self.context.get('request').query_params.get('recipes_limit') diff --git a/backend/api/urls.py b/backend/api/urls.py index 1b0f63f..d903b4d 100644 --- a/backend/api/urls.py +++ b/backend/api/urls.py @@ -1,13 +1,10 @@ -from django.urls import path, include +from django.urls import include, path from rest_framework.routers import DefaultRouter -from .views import (UserMe, TagsViewSet, RecipeViewSet, - FavoriteViewSet, - FollowViewSet, - FollowListViewSet, - IngredientViewSet, - ShoppingCartViewSet) from .utils import DownloadViewSet +from .views import (FavoriteViewSet, FollowListViewSet, FollowViewSet, + IngredientViewSet, RecipeViewSet, ShoppingCartViewSet, + TagsViewSet, UserMe) router = DefaultRouter() router.register('tags', diff --git a/backend/api/utils.py b/backend/api/utils.py index 9f155d4..b625b55 100644 --- a/backend/api/utils.py +++ b/backend/api/utils.py @@ -1,8 +1,8 @@ -from django.http import HttpResponse from django.db.models import Sum -from rest_framework.views import APIView -from rest_framework.permissions import IsAuthenticated +from django.http import HttpResponse from rest_framework import status +from rest_framework.permissions import IsAuthenticated +from rest_framework.views import APIView from recipes.models import RecipeIngredient, ShoppingCart diff --git a/backend/api/views.py b/backend/api/views.py index dab87b7..180c969 100644 --- a/backend/api/views.py +++ b/backend/api/views.py @@ -1,23 +1,24 @@ -from django.db.models import Count 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 viewsets, mixins, status +from rest_framework import mixins, status, viewsets +from rest_framework.decorators import action from rest_framework.permissions import (AllowAny, IsAuthenticated, IsAuthenticatedOrReadOnly) from rest_framework.response import Response -from rest_framework.decorators import action from rest_framework.views import APIView from core.pagination import CustomPagination -from recipes.models import (Tag, Recipe, Favorite, Follow, - Ingredient, ShoppingCart) -from .serializers import (UserSerializer, TagSerializer, RecipeSerializer, - RecipeCreateSerializer, UserMeSerializer, - FavoriteSerializer, FollowSerializer, - IngredientSerializer, ShoppingCartSerializer) +from recipes.models import (Favorite, Follow, Ingredient, Recipe, ShoppingCart, + Tag) + +from .filters import IngredientFilter, RecipeFilter from .permissions import IsOwnerOrReadOnly -from .filters import RecipeFilter, IngredientFilter +from .serializers import (FavoriteSerializer, FollowSerializer, + IngredientSerializer, RecipeCreateSerializer, + RecipeSerializer, ShoppingCartSerializer, + TagSerializer, UserMeSerializer, UserSerializer) User = get_user_model() diff --git a/backend/core/management/commands/import.py b/backend/core/management/commands/import.py index b61c8d3..500a5e4 100644 --- a/backend/core/management/commands/import.py +++ b/backend/core/management/commands/import.py @@ -1,6 +1,7 @@ -from io import open import json import os +from io import open + from django.core.management.base import BaseCommand from recipes.models import Ingredient as Ingrt diff --git a/backend/core/management/commands/test.py b/backend/core/management/commands/test.py index 22663f4..2119777 100644 --- a/backend/core/management/commands/test.py +++ b/backend/core/management/commands/test.py @@ -2,7 +2,6 @@ from django.core.management.base import BaseCommand from django.db.models import Count - from recipes.models import Follow User = get_user_model() diff --git a/backend/core/pagination.py b/backend/core/pagination.py index 9bd873a..211dc66 100644 --- a/backend/core/pagination.py +++ b/backend/core/pagination.py @@ -1,5 +1,5 @@ -from rest_framework.pagination import PageNumberPagination from django.conf import settings +from rest_framework.pagination import PageNumberPagination class CustomPagination(PageNumberPagination): diff --git a/backend/foodgram/urls.py b/backend/foodgram/urls.py index 9666b6b..1e1118c 100644 --- a/backend/foodgram/urls.py +++ b/backend/foodgram/urls.py @@ -1,5 +1,5 @@ from django.contrib import admin -from django.urls import path, include +from django.urls import include, path urlpatterns = [ path('admin/', admin.site.urls), diff --git a/backend/recipes/admin.py b/backend/recipes/admin.py index 73d1875..80cb9eb 100644 --- a/backend/recipes/admin.py +++ b/backend/recipes/admin.py @@ -1,8 +1,8 @@ -from django.contrib.auth import get_user_model from django.contrib import admin +from django.contrib.auth import get_user_model -from .models import (Tag, Ingredient, Recipe, RecipeIngredient, Favorite, - ShoppingCart, Follow, RecipeTag) +from .models import (Favorite, Follow, Ingredient, Recipe, RecipeIngredient, + RecipeTag, ShoppingCart, Tag) User = get_user_model() @@ -52,8 +52,8 @@ class RecipeAdmin(admin.ModelAdmin): 'text', 'cooking_time', 'get_tag', - 'get_in_shopping_card', - 'get_is_favorited', + # 'get_in_shopping_card', + # 'get_is_favorited', 'pub_date', 'get_favorite_counter', ) @@ -67,19 +67,9 @@ def get_tag(self, obj): return ", ".join([p.name for p in obj.tags.all()]) get_tag.short_description = 'Теги' - def get_in_shopping_card(self, obj): - """Позволяет увидеть все добавленные Список покупок.""" - return ", ".join([p.username for p in obj.is_in_shopping_cart.all()]) - get_in_shopping_card.short_description = 'В Списке покупок' - - def get_is_favorited(self, obj): - """Позволяет увидеть все добавленные в Избранное.""" - return ", ".join([p.username for p in obj.is_favorited.all()]) - get_is_favorited.short_description = 'В избранном' - def get_favorite_counter(self, obj): """Позволяет увидеть кол-во добавлений в Избранное.""" - return obj.is_favorited.all().count() + return Favorite.objects.filter(recipe=obj).count() get_favorite_counter.short_description = 'Всего в Избранном' diff --git a/backend/recipes/migrations/0001_initial.py b/backend/recipes/migrations/0001_initial.py index 839232c..d0cc087 100644 --- a/backend/recipes/migrations/0001_initial.py +++ b/backend/recipes/migrations/0001_initial.py @@ -1,8 +1,9 @@ # Generated by Django 3.2.16 on 2023-11-06 10:30 +import django.db.models.deletion from django.conf import settings from django.db import migrations, models -import django.db.models.deletion + import recipes.validators diff --git a/backend/recipes/migrations/0005_recipe_pub_date.py b/backend/recipes/migrations/0005_recipe_pub_date.py index f00bde7..3e9c73f 100644 --- a/backend/recipes/migrations/0005_recipe_pub_date.py +++ b/backend/recipes/migrations/0005_recipe_pub_date.py @@ -1,7 +1,7 @@ # Generated by Django 3.2.16 on 2023-11-08 12:02 -from django.db import migrations, models import django.utils.timezone +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/backend/recipes/migrations/0007_auto_20231111_0536.py b/backend/recipes/migrations/0007_auto_20231111_0536.py index 0156407..79a87c1 100644 --- a/backend/recipes/migrations/0007_auto_20231111_0536.py +++ b/backend/recipes/migrations/0007_auto_20231111_0536.py @@ -1,6 +1,7 @@ # Generated by Django 3.2.16 on 2023-11-11 01:36 from django.db import migrations, models + import recipes.validators diff --git a/backend/recipes/migrations/0008_auto_20231111_1154.py b/backend/recipes/migrations/0008_auto_20231111_1154.py new file mode 100644 index 0000000..ac73cbf --- /dev/null +++ b/backend/recipes/migrations/0008_auto_20231111_1154.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.16 on 2023-11-11 07:54 + +from django.db import migrations, models + +import recipes.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('recipes', '0007_auto_20231111_0536'), + ] + + operations = [ + migrations.RemoveField( + model_name='recipe', + name='is_favorited', + ), + migrations.RemoveField( + model_name='recipe', + name='is_in_shopping_cart', + ), + migrations.AlterField( + model_name='recipeingredient', + name='amount', + field=models.IntegerField(validators=[recipes.validators.amount_validator], verbose_name='Количество'), + ), + ] diff --git a/backend/recipes/models.py b/backend/recipes/models.py index f95c801..dfe57eb 100644 --- a/backend/recipes/models.py +++ b/backend/recipes/models.py @@ -1,7 +1,7 @@ from django.contrib.auth import get_user_model from django.db import models -from .validators import time_validator, amount_validator +from .validators import amount_validator, time_validator User = get_user_model() @@ -56,12 +56,6 @@ class Recipe(models.Model): ingredients = models.ManyToManyField(Ingredient, through='RecipeIngredient', blank=False,) - is_favorited = models.ManyToManyField(User, - through='Favorite', - related_name='recipes') - is_in_shopping_cart = models.ManyToManyField(User, - through='ShoppingCart', - related_name='products') pub_date = models.DateTimeField('Дата публикации', auto_now_add=True) diff --git a/backend/users/admin.py b/backend/users/admin.py index 6850d77..f7d7e4a 100644 --- a/backend/users/admin.py +++ b/backend/users/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from django.contrib.auth.admin import UserAdmin from django.contrib.auth import get_user_model +from django.contrib.auth.admin import UserAdmin User = get_user_model() diff --git a/backend/users/migrations/0001_initial.py b/backend/users/migrations/0001_initial.py index 1a6508d..13df8b1 100644 --- a/backend/users/migrations/0001_initial.py +++ b/backend/users/migrations/0001_initial.py @@ -2,8 +2,8 @@ import django.contrib.auth.models import django.contrib.auth.validators -from django.db import migrations, models import django.utils.timezone +from django.db import migrations, models class Migration(migrations.Migration):