diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..02b0920 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,129 @@ +name: Main Foodgram workflow + +on: push + +jobs: + tests: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:13.10 + env: + POSTGRES_USER: foodgram_user + POSTGRES_PASSWORD: foodgram_password + POSTGRES_DB: foodgram_db + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + steps: + - name: Check out code + uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.9 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install flake8==6.0.0 + pip install -r ./backend/requirements.txt + - name: Test with flake8 and django tests + env: + POSTGRES_USER: foodgram_user + POSTGRES_PASSWORD: foodgram_password + POSTGRES_DB: foodgram_db + DB_HOST: 127.0.0.1 + DB_PORT: 5432 + run: | + python -m flake8 backend/ + cd backend/ + python manage.py test + + + build_backend_and_push_to_docker_hub: + name: Push Backend Docker image to DockerHub + runs-on: ubuntu-latest + needs: tests + steps: + - name: Check out the repo + uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login to Docker + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Push to DockerHub + uses: docker/build-push-action@v4 + with: + context: ./backend/ + push: true + tags: ${{ secrets.DOCKER_USERNAME }}/foodgram_backend:latest + + build_frontend_and_push_to_docker_hub: + name: Push frontend Docker image to DockerHub + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login to Docker + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Push to DockerHub + uses: docker/build-push-action@v4 + with: + context: ./frontend/ + push: true + tags: ${{ secrets.DOCKER_USERNAME }}/foodgram_frontend:latest + + + deploy: + runs-on: ubuntu-latest + needs: + - build_backend_and_push_to_docker_hub + - build_frontend_and_push_to_docker_hub + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + - name: Copy docker-compose.yml via ssh + uses: appleboy/scp-action@master + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USER }} + key: ${{ secrets.SSH_KEY }} + passphrase: ${{ secrets.SSH_PASSPHRASE }} + source: "docker-compose.production.yml" + target: "foodgram" + - name: Executing remote ssh commands to deploy + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USER }} + key: ${{ secrets.SSH_KEY }} + passphrase: ${{ secrets.SSH_PASSPHRASE }} + script: | + cd foodgram + sudo docker compose -f docker-compose.production.yml pull + sudo docker compose -f docker-compose.production.yml down + sudo docker compose -f docker-compose.production.yml up -d + sudo docker compose -f docker-compose.production.yml exec backend python manage.py migrate + sudo docker compose -f docker-compose.production.yml exec backend python manage.py collectstatic + sudo docker compose -f docker-compose.production.yml exec backend cp -r /app/collected_static/. /backend_static/static/ + + + send_message: + runs-on: ubuntu-latest + needs: deploy + steps: + - name: Send message + uses: appleboy/telegram-action@master + with: + to: ${{ secrets.TELEGRAM_TO }} + token: ${{ secrets.TELEGRAM_TOKEN }} + message: Деплой успешно выполнен! https://github.com/${{ github.repository }}/commit/${{github.sha}} \ No newline at end of file diff --git a/README.md b/README.md index ffee0a4..3917f6d 100644 --- a/README.md +++ b/README.md @@ -1 +1,95 @@ -# praktikum_new_diplom + +# Foodgram +Проект "Продуктовый помошник" (Foodgram) — сайт с рецептами. + +## Технологии: +Python 3.9 +Django 3.2.3 +djangorestframework 3.12.4 +Nginx +gunicorn +Docker + +## Описание работы: +В проекте "Проуктовый помощник" любители вкусно готовить могут публиковать рецепты, добавлять чужие рецепты в избранное и подписываться на публикации других авторов. Пользователям сайта также будет доступен сервис «Список покупок». Он позволит создавать список продуктов, которые нужно купить для приготовления выбранных блюд. + +## Установка проекта +- Сделайте fork репозитория, затем клонируйте его: +``` +git clone https://github.com/ZebraHr/foodgram-project-reactl +``` +- Для адаптации проекта на своем удаленном сервере добавьте секреты в GitHub Actions: +``` +DOCKER_USERNAME # имя пользователя в DockerHub +DOCKER_PASSWORD # пароль пользователя в DockerHub +HOST # ip_address сервера +USER # имя пользователя +SSH_KEY # приватный ssh-ключ (cat ~/.ssh/id_rsa) +SSH_PASSPHRASE # кодовая фраза (пароль) для ssh-ключа + +TELEGRAM_TO # id телеграм-аккаунта (можно узнать у @userinfobot, команда /start) +TELEGRAM_TOKEN # токен бота (получить токен можно у @BotFather, /token, имя бота) +``` +- На удаленном сервере создайте папку foodgram/ +- На удаленном сервере в папке проекта cоздайте файл .env: +``` +POSTGRES_DB=<Желаемое_имя_базы_данных> +POSTGRES_USER=<Желаемое_имя_пользователя_базы_данных> +POSTGRES_PASSWORD=<Желаемый_пароль_пользователя_базы_данных> +DB_HOST=db +DB_PORT=5432 + +SECRET_KEY = 'ваш_secret_key' +ALLOWED_HOSTS = ip_удаленного сервера, 127.0.0.1, localhost +DEBUG = False +``` +- Установка Nginx. Находясь на удалённом сервере, из любой директории выполните команду, затем запустите Nginx: +``` +sudo apt install nginx -y +sudo systemctl start nginx +``` +- Перейдите в файл конфигурации nginx и измените его настройки на следующие: +``` +nano /etc/nginx/sites-enabled/default +``` +``` +server { + server_name server_name <публичный-IP-адрес> <доменное-имя>; + server_tokens_off; + client_max_body_size 30M; + + location / { + proxy_set_header Host $http_host; + proxy_pass http://127.0.0.1:8000; + } + +} +``` +- Перезарузите Nginx: +``` +sudo nginx -t +sudo systemctl reload nginx +``` +- Откройте порты для фаервола и активируйте его: +``` +sudo ufw allow 'Nginx Full' +sudo ufw allow OpenSSH +sudo ufw enable +``` +- (Опционально) Получите SSL-сертификат для вашего доменного имени с помощью Certbot: +``` +sudo apt install snapd +sudo snap install core; sudo snap refresh core +sudo snap install --classic certbot +sudo ln -s /snap/bin/certbot /usr/bin/certbot +sudo certbot --nginx +``` +- Пуш в любую ветку запускает тестирование и деплой Foodgram на ваш удаленный сервер, а после успешного деплоя вам приходит оповещение в телеграм. + +### Автор +Анна Победоносцева + +Студент Яндекс Практикума ["Python-разаботчик плюс"](https://practicum.yandex.ru/python-developer-plus/?from=catalog) + +GitHub: +(https://github.com/ZebraHr) diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..e0c8d9d --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,6 @@ +venv +.git +db.sqlite3 +.idea +.vscode +.env \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..baad26f --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.9 + +WORKDIR /app + +COPY requirements.txt ./ + +RUN pip install -r requirements.txt --no-cache-dir + +COPY . . + +CMD ["gunicorn", "--bind", "0.0.0.0:8000", "foodgram.wsgi"] \ No newline at end of file diff --git a/backend/api/__init__.py b/backend/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/api/apps.py b/backend/api/apps.py new file mode 100644 index 0000000..66656fd --- /dev/null +++ b/backend/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/backend/api/filters.py b/backend/api/filters.py new file mode 100644 index 0000000..41fad0d --- /dev/null +++ b/backend/api/filters.py @@ -0,0 +1,53 @@ +from django_filters.rest_framework import filters, FilterSet +from recipes.models import Recipe, Ingredient +from users.models import User + + +class IngredientFilter(FilterSet): + name = filters.CharFilter(lookup_expr='istartswith') + + class Meta: + model = Ingredient + fields = ('name',) + + +IN_NOT_IN = ( + (0, 'Not_In'), + (1, 'In'), +) + + +class RecipeFilter(FilterSet): + """Фильтрация рецептов.""" + + author = filters.ModelChoiceFilter( + queryset=User.objects.all() + ) + is_in_shopping_cart = filters.ChoiceFilter( + choices=IN_NOT_IN, method='get_is_in' + ) + is_favorited = filters.ChoiceFilter( + choices=IN_NOT_IN, + method='get_is_in' + ) + tags = filters.AllValuesMultipleFilter( + field_name='tags__slug', + label='Ссылка' + ) + + def get_is_in(self, queryset, name, value): + """ + Фильтрация рецептов по избранному и списку покупок. + """ + user = self.request.user + if user.is_authenticated: + if value == '1': + if name == 'is_favorited': + queryset = queryset.filter(favorites_recipes__user=user) + if name == 'is_in_shopping_cart': + queryset = queryset.filter(shopping_cart__user=user) + return queryset + + class Meta: + model = Recipe + fields = ['is_favorited', 'is_in_shopping_cart', 'author', 'tags'] diff --git a/backend/api/migrations/__init__.py b/backend/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/api/paginations.py b/backend/api/paginations.py new file mode 100644 index 0000000..6beb5cd --- /dev/null +++ b/backend/api/paginations.py @@ -0,0 +1,7 @@ +from rest_framework.pagination import PageNumberPagination + + +class RecipePagination(PageNumberPagination): + """Паджинация рецептов.""" + page_size = 6 + page_size_query_param = 'limit' diff --git a/backend/api/permissions.py b/backend/api/permissions.py new file mode 100644 index 0000000..3f93115 --- /dev/null +++ b/backend/api/permissions.py @@ -0,0 +1,20 @@ +from rest_framework.permissions import SAFE_METHODS, BasePermission + + +class IsOwnerOrReadOnly(BasePermission): + def has_object_permission(self, request, view, obj): + return request.method in SAFE_METHODS or obj.author == request.user + + +class IsAmdinOrReadOnly(BasePermission): + + def has_permission(self, request, view): + return (request.method in SAFE_METHODS + or ( + request.user.is_authenticated + and (request.user.is_admin or request.user.is_superuser))) + +# class IsAdminOrReadOnly(BasePermission): +# def has_permission(self, request, view): +# return (request.method in SAFE_METHODS +# or request.user and request.user.is_staff) diff --git a/backend/api/serializers.py b/backend/api/serializers.py new file mode 100644 index 0000000..db71959 --- /dev/null +++ b/backend/api/serializers.py @@ -0,0 +1,273 @@ +import base64 + +import webcolors +from django.core.files.base import ContentFile +from djoser.serializers import (UserCreateSerializer, + UserSerializer) +from rest_framework import serializers +from rest_framework.relations import SlugRelatedField + +from recipes.models import (Ingredient, + Tag, + Recipe, + Favorite, + ShoppingCart, + Subscribe, + IngredientAmount) +from users.models import User + + +class Base64ImageFieldSerializer(serializers.ImageField): + """Сериализатор для декодирования картинки. + Декодирует строку base64.""" + def to_internal_value(self, data): + if isinstance(data, str) and data.startswith('data:image'): + format, imgstr = data.split(';base64,') + ext = format.split('/')[-1] + data = ContentFile(base64.b64decode(imgstr), name='temp.' + ext) + + return super().to_internal_value(data) + + +class UserCreateSerializer(UserCreateSerializer): + """Создание пользователя с обязательными полями.""" + class Meta: + model = User + fields = ('email', 'username', 'first_name', 'last_name', 'password') + required_fields = ( + 'email', + 'username', + 'first_name', + 'last_name', + 'password' + ) + + +class UserReadSerializer(UserSerializer): + """Страница пользователя.""" + is_subscribed = serializers.SerializerMethodField() + + class Meta: + model = User + fields = ('id', 'email', 'username', 'first_name', + 'last_name', 'is_subscribed') + + def get_is_subscribed(self, obj): + request = self.context.get('request') + if request.user.is_anonymous: + return False + return Subscribe.objects.filter(user=request.user, author=obj).exists() + + +class IngredientSerializer(serializers.ModelSerializer): + """Ингредиенты в рецепте.""" + + class Meta: + fields = '__all__' + model = Ingredient + + +class IngredientsInRecipeSerializer(serializers.ModelSerializer): + """Игредиенты в рецепте.""" + id = serializers.ReadOnlyField( + source='ingredient.id', + ) + name = serializers.ReadOnlyField( + source='ingredient.name', + ) + measurement_unit = serializers.ReadOnlyField( + source='ingredient.measurement_unit', + ) + + class Meta: + model = IngredientAmount + fields = ('id', 'name', 'measurement_unit', 'amount') + + +class TagSerializer(serializers.ModelSerializer): + """Теги.""" + class Meta: + fields = '__all__' + model = Tag + + +class IngredientInRecipeWriteSerializer(serializers.ModelSerializer): + """Сериализатор для игредиентов в рецепте.""" + id = serializers.PrimaryKeyRelatedField(queryset=Ingredient.objects.all()) + + class Meta: + model = IngredientAmount + fields = ('id', 'amount') + + +class RecipeCreateSerializer(serializers.ModelSerializer): + """Серилизатор для создания рецепта.""" + image = Base64ImageFieldSerializer( + required=False, + allow_null=True + ) + author = SlugRelatedField( + slug_field='username', + read_only=True + ) + ingredients = IngredientInRecipeWriteSerializer( + many=True + ) + tags = serializers.PrimaryKeyRelatedField( + queryset=Tag.objects.all(), + many=True + ) + cooking_time = serializers.IntegerField(read_only=True) + + class Meta: + model = Recipe + fields = ('id', 'ingredients', 'tags', + 'image', 'name', 'text', + 'cooking_time', 'author') + + def create_ingredients(self, ingredients, recipe): + IngredientAmount.objects.bulk_create([ + IngredientAmount( + ingredient=ingredient.get('id'), + recipe=recipe, + amount=ingredient.get('amount') + ) + for ingredient in ingredients + ]) + + def create(self, validated_data): + tags = validated_data.pop('tags') + ingredients = validated_data.pop('ingredients') + recipe = Recipe.objects.create(**validated_data) + recipe.tags.set(tags) + self.create_ingredients(ingredients, recipe) + return recipe + + def update(self, instance, validated_data): + recipe = instance + instance.image = validated_data.get('image', instance.image) + instance.name = validated_data.get('name', instance.name) + instance.text = validated_data.get('text', instance.name) + instance.cooking_time = validated_data.get( + 'cooking_time', + instance.cooking_time + ) + instance.tags.clear() + instance.ingredients.clear() + tags = validated_data.get('tags') + instance.tags.set(tags) + ingredients = validated_data.get('ingredients') + IngredientAmount.objects.filter(recipe=recipe).delete() + self.create_ingredients(ingredients, recipe) + instance.save() + return instance + + def to_representation(self, instance): + return RecipeReadSerializer(instance, context={ + 'request': self.context.get('request') + }).data + + +class Hex2NameColor(serializers.Field): + """Сериализатор для добавления цветов через HEX.""" + def to_representation(self, value): + return value + + def to_internal_value(self, data): + try: + data = webcolors.hex_to_name(data) + except ValueError: + raise serializers.ValidationError('Для этого цвета нет имени') + return data + + +class RecipeReadSerializer(serializers.ModelSerializer): + """Просмотр рецепта.""" + tags = TagSerializer( + many=True, + ) + ingredients = IngredientsInRecipeSerializer( + many=True, + source='recipe' + ) + author = UserReadSerializer() + is_favorited = serializers.SerializerMethodField() + is_in_shopping_cart = serializers.SerializerMethodField() + + class Meta: + model = Recipe + fields = ( + 'id', 'tags', 'author', 'ingredients', + 'is_favorited', + 'name', 'image', 'text', 'cooking_time', + 'is_in_shopping_cart', + ) + + def get_is_favorited(self, obj): + request = self.context.get('request') + if request.user.is_anonymous: + return False + return Favorite.objects.filter(recipe=obj, + user=request.user).exists() + + def get_is_in_shopping_cart(self, obj): + request = self.context.get('request') + if request.user.is_anonymous: + return False + return ShoppingCart.objects.filter(recipe=obj, + user=request.user).exists() + + +class SubscribeSerializer(serializers.ModelSerializer): + """Информация о подписке. + Данные о пользователе, на которого + сделана подписка.""" + + recipes_count = serializers.SerializerMethodField() + is_subscribed = serializers.SerializerMethodField() + recipes = serializers.SerializerMethodField() + + class Meta: + model = User + fields = ( + 'email', + 'id', + 'username', + 'first_name', + 'last_name', + 'is_subscribed', + 'recipes', + 'recipes_count', + ) + + def get_recipes_count(self, obj): + return Recipe.objects.filter(author=obj).count() + + def get_is_subscribed(self, obj): + user = self.context['request'].user + if user.is_anonymous: + return False + return Subscribe.objects.filter(user=user, author=obj).exists() + + def get_recipes(self, obj): + request = self.context.get('request') + limit_recipes = request.query_params.get('recipes_limit') + if limit_recipes is not None: + recipes = obj.recipes.all()[:(int(limit_recipes))] + else: + recipes = obj.recipes.all() + return RecipeShortSerializer(recipes, many=True, + context={'request': request}).data + + +class RecipeShortSerializer(serializers.ModelSerializer): + image = Base64ImageFieldSerializer() + + class Meta: + model = Recipe + fields = ( + 'id', + 'name', + 'image', + 'cooking_time' + ) diff --git a/backend/api/urls.py b/backend/api/urls.py new file mode 100644 index 0000000..f4c11ba --- /dev/null +++ b/backend/api/urls.py @@ -0,0 +1,23 @@ +from rest_framework.routers import DefaultRouter +from django.urls import include, path + +from api.views import (IngredientViewSet, + TagViewSet, + CustomUserViewSet, + RecipeViewSet, + ) + +app_name = 'api' + +router = DefaultRouter() +router.register('users', CustomUserViewSet, basename='users') +router.register('ingredients', IngredientViewSet) +router.register('tags', TagViewSet) +router.register('recipes', RecipeViewSet, basename='recipe') + + +urlpatterns = [ + path('', include(router.urls)), + path('', include('djoser.urls')), + path('auth/', include('djoser.urls.authtoken')), +] diff --git a/backend/api/views.py b/backend/api/views.py new file mode 100644 index 0000000..0a58cdf --- /dev/null +++ b/backend/api/views.py @@ -0,0 +1,225 @@ +from rest_framework import viewsets, status +from django.shortcuts import get_object_or_404 +from rest_framework.viewsets import ReadOnlyModelViewSet +from rest_framework.permissions import (IsAuthenticatedOrReadOnly, + IsAuthenticated, + # AllowAny, + SAFE_METHODS) +from rest_framework.filters import SearchFilter +from rest_framework.response import Response +from djoser.views import UserViewSet +from rest_framework.decorators import action +from django_filters.rest_framework import DjangoFilterBackend +import io +from django.http import FileResponse +from reportlab.pdfgen import canvas +from reportlab.pdfbase import pdfmetrics, ttfonts +from django.db.models import Sum +from django.conf import settings + +from api.serializers import (UserCreateSerializer, + UserReadSerializer, + IngredientSerializer, + TagSerializer, + RecipeCreateSerializer, + RecipeReadSerializer, + SubscribeSerializer, + RecipeShortSerializer + ) +from recipes.models import (Ingredient, + Tag, + Recipe, + Favorite, + ShoppingCart, + Subscribe, + IngredientAmount) +from users.models import User +from api.permissions import IsAmdinOrReadOnly, IsOwnerOrReadOnly +from api.paginations import RecipePagination +from api.filters import RecipeFilter, IngredientFilter + + +class CustomUserViewSet(UserViewSet): + """Вьюсет для просмотра профиля и создания пользователя.""" + queryset = User.objects.all() + permission_classes = [IsAuthenticatedOrReadOnly, ] + pagination_class = RecipePagination + + def get_serializer_class(self): + if self.action == 'create': + return UserCreateSerializer + return UserReadSerializer + + @action( + detail=True, + methods=['post', 'delete'], + permission_classes=[IsAuthenticated, ], + url_path='subscribe' + ) + def subscribe(self, request, id=None): + user = self.request.user + author = get_object_or_404(User, pk=id) + if request.method == 'POST': + if user == author: + return Response({'errors': 'На себя подписаться нельзя!'}, + status=status.HTTP_400_BAD_REQUEST) + if Subscribe.objects.filter(user=user, + author=author).exists(): + return Response({'errors': + 'Вы уже подписаны на этого пользователя!'}, + status=status.HTTP_400_BAD_REQUEST) + + Subscribe.objects.create(user=user, author=author) + serializer = SubscribeSerializer(author, + context={'request': request} + ) + + return Response(serializer.data, + status=status.HTTP_201_CREATED) + + if request.method == 'DELETE': + subscription = Subscribe.objects.filter(user=user, author=author) + if subscription.exists(): + subscription.delete() + return Response( + {'message': 'Вы больше не подписаны на пользователя'}, + status=status.HTTP_204_NO_CONTENT) + return Response( + {'errors': 'Вы не подписаны на этого пользователя!'}, + status=status.HTTP_400_BAD_REQUEST) + + @action( + detail=False, + permission_classes=[IsAuthenticated, ], + ) + def subscriptions(self, request): + queryset = User.objects.filter(subscribing__user=request.user) + pag_queryset = self.paginate_queryset(queryset) + serializer = SubscribeSerializer(pag_queryset, + many=True, + context={'request': request}) + return self.get_paginated_response(serializer.data) + + +class IngredientViewSet(ReadOnlyModelViewSet): + """Вьюсет для просмотра ингредиентов.""" + queryset = Ingredient.objects.all() + permission_classes = [IsAmdinOrReadOnly] + serializer_class = IngredientSerializer + filter_backends = (SearchFilter,) + filterset_class = IngredientFilter + search_fields = ('^name',) + + +class TagViewSet(ReadOnlyModelViewSet): + """Вьюсет для просмотра тегов.""" + queryset = Tag.objects.all() + serializer_class = TagSerializer + permission_classes = [IsAmdinOrReadOnly] + + +class RecipeViewSet(viewsets.ModelViewSet): + """Вьюсет рецепта. + Просмотр, создание, редактирование.""" + queryset = Recipe.objects.all() + permission_classes = [IsOwnerOrReadOnly | IsAmdinOrReadOnly] + pagination_class = RecipePagination + filter_backends = (DjangoFilterBackend,) + filterset_class = RecipeFilter + + def perform_create(self, serializer): + serializer.save(author=self.request.user) + + def get_serializer_class(self): + if self.request.method in SAFE_METHODS: + return RecipeReadSerializer + return RecipeCreateSerializer + + @action( + detail=True, + methods=['post', 'delete'], + permission_classes=[IsAuthenticated] + ) + def favorite(self, request, pk): + if request.method == 'POST': + if Favorite.objects.filter(user=request.user, + recipe__id=pk).exists(): + return Response({'errors': 'Рецепт уже добавлен!'}, + status=status.HTTP_400_BAD_REQUEST) + recipe = get_object_or_404(Recipe, id=pk) + Favorite.objects.create(user=request.user, recipe=recipe) + serializer = RecipeReadSerializer(recipe, + context={'request': request}) + return Response(serializer.data, status=status.HTTP_201_CREATED) + if request.method == 'DELETE': + fav_rec = Favorite.objects.filter(user=request.user, recipe__id=pk) + if fav_rec.exists(): + fav_rec.delete() + return Response( + {'message': 'Рецепт удален из избранного'}, + status=status.HTTP_204_NO_CONTENT) + return Response( + {'errors': 'Рецепт уже удален!'}, + status=status.HTTP_400_BAD_REQUEST) + + @action( + detail=True, + methods=['post', 'delete'], + permission_classes=[IsAuthenticated], + pagination_class=None + ) + def shopping_cart(self, request, pk): + if request.method == 'POST': + if ShoppingCart.objects.filter(user=request.user, + recipe__id=pk).exists(): + return Response({'errors': + 'Рецепт уже добавлен в список покупок!'}, + status=status.HTTP_400_BAD_REQUEST) + recipe = get_object_or_404(Recipe, id=pk) + ShoppingCart.objects.create(user=request.user, recipe=recipe) + serializer = RecipeShortSerializer(recipe, + context={'request': request}) + return Response(serializer.data, status=status.HTTP_201_CREATED) + if request.method == 'DELETE': + rec_in_cart = ShoppingCart.objects.filter(user=request.user, + recipe__id=pk) + if rec_in_cart.exists(): + rec_in_cart.delete() + return Response( + {'message': 'Рецепт удален из списка покупок'}, + status=status.HTTP_204_NO_CONTENT) + return Response( + {'errors': 'Рецепт уже удален из списка покупок!'}, + status=status.HTTP_400_BAD_REQUEST) + + @action( + detail=False, + methods=['get'], + permission_classes=(IsAuthenticated,)) + def download_shopping_cart(self, request): + user = request.user + buffer = io.BytesIO() + ingredients = IngredientAmount.objects.filter( + recipe__shopping_cart__user=user).values( + 'ingredient__name', 'ingredient__measurement_unit').annotate( + amount=Sum('amount')) + shopping_list = ([f'{i["ingredient__name"]}' + f' ({i["ingredient__measurement_unit"]})' + f' - {i["amount"]}' + for i in ingredients]) + text = canvas.Canvas(buffer) + font = ttfonts.TTFont('Arial', './docs/arialfont.ttf') + pdfmetrics.registerFont(font) + text.setFont('Arial', settings.HEAD_FONT_SIZE) + text.drawString(settings.HEAD_INDENT, settings.HEAD_HEIGHT, + 'Ваш список покупок:') + text.setFont('Arial', settings.TEXT_FONT_SIZE) + for line in shopping_list: + text.drawString(settings.TEXT_INDENT, settings.TEXT_HEIGHT, line) + settings.TEXT_HEIGHT -= settings.LINE_SPACE + text.showPage() + text.save() + buffer.seek(0) + return FileResponse(buffer, + as_attachment=True, + filename='shopping_cart.pdf') diff --git a/backend/docs/TNRfont.ttf b/backend/docs/TNRfont.ttf new file mode 100644 index 0000000..51261a0 Binary files /dev/null and b/backend/docs/TNRfont.ttf differ diff --git a/backend/docs/arialfont.ttf b/backend/docs/arialfont.ttf new file mode 100644 index 0000000..a882d32 Binary files /dev/null and b/backend/docs/arialfont.ttf differ diff --git a/backend/foodgram/__init__.py b/backend/foodgram/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/foodgram/asgi.py b/backend/foodgram/asgi.py new file mode 100644 index 0000000..fa20cbb --- /dev/null +++ b/backend/foodgram/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for foodgram project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'foodgram.settings') + +application = get_asgi_application() diff --git a/backend/foodgram/settings.py b/backend/foodgram/settings.py new file mode 100644 index 0000000..a9c2f90 --- /dev/null +++ b/backend/foodgram/settings.py @@ -0,0 +1,187 @@ +""" +Django settings for foodgram project. + +Generated by 'django-admin startproject' using Django 4.2.4. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" +import os +from pathlib import Path + +from dotenv import load_dotenv + +load_dotenv() + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ + +SECRET_KEY = os.getenv('SECRET_KEY', 'django-secret-key') + +DEBUG = os.getenv('DEBUG', 'False').lower() == 'true' + +ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', default='localhost').split(', ') + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'rest_framework.authtoken', + 'rest_framework', + 'djoser', + 'import_export', + 'django_filters', + 'users.apps.UsersConfig', + 'api.apps.ApiConfig', + 'recipes.apps.RecipesConfig', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'foodgram.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'foodgram.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases + + +if DEBUG: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } + } +else: + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': os.getenv('POSTGRES_DB', 'django'), + 'USER': os.getenv('POSTGRES_USER', 'django'), + 'PASSWORD': os.getenv('POSTGRES_PASSWORD', ''), + 'HOST': os.getenv('DB_HOST', ''), + 'PORT': os.getenv('DB_PORT', 5432) + } + } + + +AUTH_USER_MODEL = 'users.User' + +# Password validation +# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +IMPORT_EXPORT_USE_TRANSACTIONS = True + +STATIC_URL = '/static/' +STATIC_ROOT = BASE_DIR / 'collected_static' + +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + + +REST_FRAMEWORK = { + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.AllowAny', + ], + + 'DEFAULT_AUTHENTICATION_CLASSES': ( + + 'rest_framework.authentication.TokenAuthentication', + ), + 'SEARCH_PARAM': 'name', +} + +DJOSER = { + 'SERIALIZERS': { + 'user_create': 'api.serializers.UserCreateSerializer', + 'user': 'api.serializers.UserReadSerializer', + 'current_user': 'api.serializers.UserReadSerializer', + }, + 'HIDE_USERS': False, +} + + +# download_shopping_cart + +HEAD_FONT_SIZE = 18 +TEXT_FONT_SIZE = 14 +HEAD_HEIGHT = 800 +HEAD_INDENT = 200 +TEXT_HEIGHT = 750 +TEXT_INDENT = 50 +LINE_SPACE = 20 diff --git a/backend/foodgram/urls.py b/backend/foodgram/urls.py new file mode 100644 index 0000000..2e1677b --- /dev/null +++ b/backend/foodgram/urls.py @@ -0,0 +1,14 @@ +from django.contrib import admin +from django.conf import settings +from django.conf.urls.static import static +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('api/', include('api.urls')), +] + +if settings.DEBUG: + urlpatterns += static( + settings.MEDIA_URL, document_root=settings.MEDIA_ROOT + ) diff --git a/backend/foodgram/wsgi.py b/backend/foodgram/wsgi.py new file mode 100644 index 0000000..edb18d5 --- /dev/null +++ b/backend/foodgram/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for foodgram project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'foodgram.settings') + +application = get_wsgi_application() diff --git a/backend/ingredients.json b/backend/ingredients.json new file mode 100644 index 0000000..9d65b61 --- /dev/null +++ b/backend/ingredients.json @@ -0,0 +1 @@ +[{"name": "абрикосовое варенье", "measurement_unit": "г"}, {"name": "абрикосовое пюре", "measurement_unit": "г"}, {"name": "абрикосовый джем", "measurement_unit": "г"}, {"name": "абрикосовый сок", "measurement_unit": "стакан"}, {"name": "абрикосы", "measurement_unit": "г"}, {"name": "абрикосы консервированные", "measurement_unit": "г"}, {"name": "авокадо", "measurement_unit": "по вкусу"}, {"name": "агава сироп", "measurement_unit": "г"}, {"name": "агар-агар", "measurement_unit": "г"}, {"name": "аграм", "measurement_unit": "г"}, {"name": "аджика", "measurement_unit": "г"}, {"name": "аджика зеленая", "measurement_unit": "г"}, {"name": "айва", "measurement_unit": "по вкусу"}, {"name": "айвовое пюре", "measurement_unit": "г"}, {"name": "айран", "measurement_unit": "г"}, {"name": "айсинг", "measurement_unit": "г"}, {"name": "акула стейки", "measurement_unit": "г"}, {"name": "алкоголь", "measurement_unit": "стакан"}, {"name": "алкоголь крепкий", "measurement_unit": "ст. л."}, {"name": "алыча", "measurement_unit": "г"}, {"name": "альбухара", "measurement_unit": "шт."}, {"name": "альмехи", "measurement_unit": "г"}, {"name": "амарантовая мука", "measurement_unit": "г"}, {"name": "ананасовый сироп", "measurement_unit": "г"}, {"name": "ананасовый сок", "measurement_unit": "г"}, {"name": "ананасы", "measurement_unit": "г"}, {"name": "ананасы вяленые", "measurement_unit": "г"}, {"name": "ананасы консервированные", "measurement_unit": "по вкусу"}, {"name": "анис", "measurement_unit": "по вкусу"}, {"name": "анис звездочки", "measurement_unit": "г"}, {"name": "анисовый ликер", "measurement_unit": "мл"}, {"name": "анис семена", "measurement_unit": "г"}, {"name": "анчоусы", "measurement_unit": "г"}, {"name": "апельсиновая вода", "measurement_unit": "г"}, {"name": "апельсиновая цедра", "measurement_unit": "г"}, {"name": "апельсиновая эссенция", "measurement_unit": "ч. л."}, {"name": "апельсиновое варенье", "measurement_unit": "г"}, {"name": "апельсиновые цукаты", "measurement_unit": "г"}, {"name": "апельсиновый джем", "measurement_unit": "г"}, {"name": "апельсиновый джем с имбирем", "measurement_unit": "г"}, {"name": "апельсиновый ликер", "measurement_unit": "г"}, {"name": "апельсиновый сироп", "measurement_unit": "стакан"}, {"name": "апельсиновый сок", "measurement_unit": "по вкусу"}, {"name": "апельсиновый сок свежевыжатый", "measurement_unit": "г"}, {"name": "апельсиновый уксус", "measurement_unit": "ст. л."}, {"name": "апельсиновый экстракт", "measurement_unit": "ч. л."}, {"name": "апельсины", "measurement_unit": "г"}, {"name": "апельсины красные", "measurement_unit": "шт."}, {"name": "апельсины крупные", "measurement_unit": "шт."}, {"name": "арахис", "measurement_unit": "г"}, {"name": "арахис жареный", "measurement_unit": "г"}, {"name": "арахисовая паста", "measurement_unit": "г"}, {"name": "арахисовое масло", "measurement_unit": "г"}, {"name": "арахис соленый", "measurement_unit": "г"}, {"name": "арбузная мякоть", "measurement_unit": "г"}, {"name": "арбузы", "measurement_unit": "г"}, {"name": "аргановое масло", "measurement_unit": "г"}, {"name": "аришта", "measurement_unit": "г"}, {"name": "ароматизатор", "measurement_unit": "г"}, {"name": "ароматизатор \"ананас\"", "measurement_unit": "по вкусу"}, {"name": "ароматизатор \"вишня\"", "measurement_unit": "капля"}, {"name": "ароматизатор \"малина\"", "measurement_unit": "капля"}, {"name": "ароматизатор \"ром\"", "measurement_unit": "г"}, {"name": "артишоки", "measurement_unit": "г"}, {"name": "артишоки в масле", "measurement_unit": "г"}, {"name": "артишоки маринованные", "measurement_unit": "г"}, {"name": "аспирин", "measurement_unit": "шт."}, {"name": "ассорти мясное", "measurement_unit": "г"}, {"name": "ассорти овощное", "measurement_unit": "г"}, {"name": "ассорти фруктовое", "measurement_unit": "г"}, {"name": "ассорти ягодное", "measurement_unit": "г"}, {"name": "аши", "measurement_unit": "г"}, {"name": "багет", "measurement_unit": "г"}, {"name": "багет вчерашний", "measurement_unit": "г"}, {"name": "багет мини", "measurement_unit": "г"}, {"name": "бадан", "measurement_unit": "звездочка"}, {"name": "бадьян", "measurement_unit": "щепотка"}, {"name": "базилик лимонный", "measurement_unit": "г"}, {"name": "базилик свежий", "measurement_unit": "г"}, {"name": "базилик сушеный", "measurement_unit": "г"}, {"name": "базилик тайский", "measurement_unit": "горсть"}, {"name": "базилик фиолетовый", "measurement_unit": "г"}, {"name": "баклажаны", "measurement_unit": "по вкусу"}, {"name": "баклажаны мини", "measurement_unit": "г"}, {"name": "баклажаны тайские", "measurement_unit": "г"}, {"name": "балык", "measurement_unit": "г"}, {"name": "бальзам", "measurement_unit": "г"}, {"name": "бальзамический крем", "measurement_unit": "стакан"}, {"name": "бальзамический соус", "measurement_unit": "ст. л."}, {"name": "бальзамический уксус", "measurement_unit": "стакан"}, {"name": "бальзам рижский черный", "measurement_unit": "ст. л."}, {"name": "бамия", "measurement_unit": "г"}, {"name": "банановое пюре", "measurement_unit": "г"}, {"name": "банановые чипсы", "measurement_unit": "горсть"}, {"name": "банановый зеленый сироп", "measurement_unit": "мл"}, {"name": "банановый ликер", "measurement_unit": "мл"}, {"name": "бананы", "measurement_unit": "г"}, {"name": "бананы мини", "measurement_unit": "г"}, {"name": "барабулька", "measurement_unit": "г"}, {"name": "бараний ливер", "measurement_unit": "г"}, {"name": "бараний окорок на косточке", "measurement_unit": "кусок"}, {"name": "бараний фарш", "measurement_unit": "г"}, {"name": "баранина", "measurement_unit": "г"}, {"name": "баранки", "measurement_unit": "г"}, {"name": "бараньи антрекоты", "measurement_unit": "кг"}, {"name": "бараньи голяшки", "measurement_unit": "шт."}, {"name": "бараньи потроха", "measurement_unit": "кг"}, {"name": "бараньи ребрышки", "measurement_unit": "шт."}, {"name": "баранья лопатка", "measurement_unit": "кг"}, {"name": "баранья нога", "measurement_unit": "г"}, {"name": "баранья печень", "measurement_unit": "г"}, {"name": "барбарис", "measurement_unit": "г"}, {"name": "барбарис вяленый", "measurement_unit": "ст. л."}, {"name": "барбарис молотый", "measurement_unit": "г"}, {"name": "бастурма", "measurement_unit": "г"}, {"name": "батат", "measurement_unit": "г"}, {"name": "батон", "measurement_unit": "г"}, {"name": "батончики шоколадные", "measurement_unit": "г"}, {"name": "безе", "measurement_unit": "г"}, {"name": "бекон", "measurement_unit": "по вкусу"}, {"name": "бекон варено-копченый", "measurement_unit": "г"}, {"name": "бекон сырокопченый", "measurement_unit": "г"}, {"name": "белорыбица", "measurement_unit": "г"}, {"name": "бирнель", "measurement_unit": "мл"}, {"name": "бисквик смесь готовая", "measurement_unit": "пакет"}, {"name": "бисквит", "measurement_unit": "г"}, {"name": "бисквитная крошка", "measurement_unit": "г"}, {"name": "бисквитный корж", "measurement_unit": "г"}, {"name": "бисквитный рулет", "measurement_unit": "г"}, {"name": "бисквит шоколадный", "measurement_unit": "г"}, {"name": "бифштекс", "measurement_unit": "шт."}, {"name": "блинная мука", "measurement_unit": "г"}, {"name": "блины готовые", "measurement_unit": "г"}, {"name": "блины овсяные", "measurement_unit": "шт."}, {"name": "бобовые ростки", "measurement_unit": "г"}, {"name": "бобы", "measurement_unit": "г"}, {"name": "бобы мунг пророщенные", "measurement_unit": "г"}, {"name": "бобы тонка", "measurement_unit": "шт."}, {"name": "ботарга", "measurement_unit": "г"}, {"name": "брезаола", "measurement_unit": "г"}, {"name": "бренди", "measurement_unit": "г"}, {"name": "брокколи замороженная", "measurement_unit": "г"}, {"name": "брокколи свежая", "measurement_unit": "г"}, {"name": "брусника замороженная", "measurement_unit": "г"}, {"name": "брусника свежая", "measurement_unit": "г"}, {"name": "брусника сушеная", "measurement_unit": "г"}, {"name": "брусничное варенье", "measurement_unit": "г"}, {"name": "брусничный соус", "measurement_unit": "г"}, {"name": "брынза", "measurement_unit": "по вкусу"}, {"name": "брынза сербская", "measurement_unit": "г"}, {"name": "брюква", "measurement_unit": "г"}, {"name": "буженина", "measurement_unit": "г"}, {"name": "бузина сироп", "measurement_unit": "ст. л."}, {"name": "букет гарни", "measurement_unit": "пучок"}, {"name": "булгур", "measurement_unit": "г"}, {"name": "булка", "measurement_unit": "кусок"}, {"name": "булка белая", "measurement_unit": "г"}, {"name": "булка сдобная", "measurement_unit": "г"}, {"name": "булочки", "measurement_unit": "г"}, {"name": "булочки белые черствые", "measurement_unit": "г"}, {"name": "булочки бриошь", "measurement_unit": "шт."}, {"name": "булочки вчерашние", "measurement_unit": "шт."}, {"name": "булочки для гамбургеров", "measurement_unit": "шт."}, {"name": "булочки зерновые", "measurement_unit": "шт."}, {"name": "булочки ржаные", "measurement_unit": "кусок"}, {"name": "булочки с кунжутом", "measurement_unit": "шт."}, {"name": "бульон", "measurement_unit": "г"}, {"name": "бульонные кубики", "measurement_unit": "г"}, {"name": "бурбон", "measurement_unit": "г"}, {"name": "Буррата", "measurement_unit": "г"}, {"name": "буряк", "measurement_unit": "г"}, {"name": "бусинки кондитерские", "measurement_unit": "ч. л."}, {"name": "бусинки кондитерские серебряные", "measurement_unit": "по вкусу"}, {"name": "бычий хвост", "measurement_unit": "г"}, {"name": "ванилин", "measurement_unit": "г"}, {"name": "ваниль в стручках", "measurement_unit": "г"}, {"name": "ванильная настойка", "measurement_unit": "ст. л."}, {"name": "ванильная эссенция", "measurement_unit": "г"}, {"name": "ванильный порошок", "measurement_unit": "г"}, {"name": "ванильный сироп", "measurement_unit": "г"}, {"name": "ванильный экстракт", "measurement_unit": "по вкусу"}, {"name": "варенье", "measurement_unit": "г"}, {"name": "васаби", "measurement_unit": "г"}, {"name": "вафельная крошка", "measurement_unit": "г"}, {"name": "вафельные коржи", "measurement_unit": "г"}, {"name": "вафельные трубочки", "measurement_unit": "г"}, {"name": "вафли", "measurement_unit": "г"}, {"name": "вафли шоколадные", "measurement_unit": "г"}, {"name": "вермишель", "measurement_unit": "г"}, {"name": "вермишель яичная", "measurement_unit": "г"}, {"name": "вермут", "measurement_unit": "г"}, {"name": "вермут белый", "measurement_unit": "г"}, {"name": "вермут сухой", "measurement_unit": "г"}, {"name": "ветчина", "measurement_unit": "г"}, {"name": "ветчина вареная", "measurement_unit": "г"}, {"name": "ветчина варено-копченая", "measurement_unit": "кусок"}, {"name": "ветчина копченая", "measurement_unit": "г"}, {"name": "ветчина пармская", "measurement_unit": "г"}, {"name": "ветчина сырокопченая", "measurement_unit": "г"}, {"name": "вешенки", "measurement_unit": "г"}, {"name": "винегрет", "measurement_unit": "г"}, {"name": "винный камень", "measurement_unit": "щепотка"}, {"name": "винный уксус", "measurement_unit": "г"}, {"name": "винный уксус белый", "measurement_unit": "г"}, {"name": "винный уксус красный", "measurement_unit": "ч. л."}, {"name": "винный уксус на чесноке", "measurement_unit": "ч. л."}, {"name": "винный уксус на эстрагоне", "measurement_unit": "ст. л."}, {"name": "вино белое", "measurement_unit": "по вкусу"}, {"name": "вино белое полусладкое", "measurement_unit": "г"}, {"name": "вино белое полусухое", "measurement_unit": "г"}, {"name": "вино белое сладкое", "measurement_unit": "г"}, {"name": "вино белое столовое", "measurement_unit": "стакан"}, {"name": "вино белое сухое", "measurement_unit": "г"}, {"name": "виноград", "measurement_unit": "г"}, {"name": "виноград без косточек", "measurement_unit": "г"}, {"name": "виноград белый", "measurement_unit": "г"}, {"name": "виноград изабелла", "measurement_unit": "кг"}, {"name": "виноградное желе", "measurement_unit": "ст. л."}, {"name": "виноградные листья", "measurement_unit": "г"}, {"name": "виноградные листья маринованные", "measurement_unit": "г"}, {"name": "виноградные листья молодые", "measurement_unit": "шт."}, {"name": "виноградный сок", "measurement_unit": "г"}, {"name": "виноградный сок осветленный", "measurement_unit": "ч. л."}, {"name": "виноград синий", "measurement_unit": "г"}, {"name": "виноград черный", "measurement_unit": "г"}, {"name": "вино десертное", "measurement_unit": "г"}, {"name": "вино игристое сухое", "measurement_unit": "г"}, {"name": "вино красное", "measurement_unit": "г"}, {"name": "вино красное полусладкое", "measurement_unit": "г"}, {"name": "вино красное полусухое", "measurement_unit": "г"}, {"name": "вино красное сладкое", "measurement_unit": "г"}, {"name": "вино красное сухое", "measurement_unit": "г"}, {"name": "вино крепленое", "measurement_unit": "г"}, {"name": "вино розовое полусладкое", "measurement_unit": "ст. л."}, {"name": "вино розовое полусухое", "measurement_unit": "г"}, {"name": "виски", "measurement_unit": "г"}, {"name": "витамин C в порошке", "measurement_unit": "г"}, {"name": "вишневая настойка", "measurement_unit": "мл"}, {"name": "вишневое варенье", "measurement_unit": "г"}, {"name": "вишневые листья", "measurement_unit": "г"}, {"name": "вишневый джем", "measurement_unit": "г"}, {"name": "вишневый ликер", "measurement_unit": "по вкусу"}, {"name": "вишневый сироп", "measurement_unit": "стакан"}, {"name": "вишневый сок", "measurement_unit": "г"}, {"name": "вишня", "measurement_unit": "г"}, {"name": "вишня вяленая", "measurement_unit": "г"}, {"name": "вишня замороженная", "measurement_unit": "г"}, {"name": "вишня засахаренная кондитерская", "measurement_unit": "шт."}, {"name": "вишня коктейльная", "measurement_unit": "г"}, {"name": "вишня мараскино", "measurement_unit": "шт."}, {"name": "вишня, протертая с сахаром", "measurement_unit": "г"}, {"name": "вода", "measurement_unit": "г"}, {"name": "вода минеральная без газа", "measurement_unit": "стакан"}, {"name": "вода минеральная газированная", "measurement_unit": "г"}, {"name": "водка", "measurement_unit": "г"}, {"name": "водка анисовая", "measurement_unit": "ч. л."}, {"name": "водоросли", "measurement_unit": "г"}, {"name": "вустерширский соус", "measurement_unit": "г"}, {"name": "галангал корень", "measurement_unit": "долька"}, {"name": "галеты", "measurement_unit": "г"}, {"name": "гамбургер", "measurement_unit": "г"}, {"name": "ганаш", "measurement_unit": "г"}, {"name": "гарам масала", "measurement_unit": "г"}, {"name": "гарнир", "measurement_unit": "г"}, {"name": "гаспачо", "measurement_unit": "г"}, {"name": "гвоздика", "measurement_unit": "г"}, {"name": "гвоздика молотая", "measurement_unit": "по вкусу"}, {"name": "герань листья", "measurement_unit": "г"}, {"name": "геркулес", "measurement_unit": "г"}, {"name": "глазурь", "measurement_unit": "г"}, {"name": "глазурь белая", "measurement_unit": "г"}, {"name": "глазурь готовая", "measurement_unit": "по вкусу"}, {"name": "глазурь черная", "measurement_unit": "по вкусу"}, {"name": "глазурь шоколадная белая", "measurement_unit": "г"}, {"name": "глутамат натрия", "measurement_unit": "г"}, {"name": "глюкоза", "measurement_unit": "г"}, {"name": "глюкоза сироп", "measurement_unit": "г"}, {"name": "говядина", "measurement_unit": "г"}, {"name": "говядина на кости", "measurement_unit": "г"}, {"name": "говяжий фарш", "measurement_unit": "по вкусу"}, {"name": "говяжий язык", "measurement_unit": "г"}, {"name": "говяжье сердце", "measurement_unit": "по вкусу"}, {"name": "говяжьи бифштексы", "measurement_unit": "г"}, {"name": "говяжьи голяшки", "measurement_unit": "г"}, {"name": "говяжьи легкие", "measurement_unit": "г"}, {"name": "говяжьи ребра", "measurement_unit": "г"}, {"name": "говяжьи стейки рибай", "measurement_unit": "г"}, {"name": "говяжья вырезка", "measurement_unit": "шт."}, {"name": "говяжья грудинка", "measurement_unit": "кг"}, {"name": "говяжья лопатка", "measurement_unit": "г"}, {"name": "говяжья мозговая кость", "measurement_unit": "шт."}, {"name": "говяжья мякоть", "measurement_unit": "кг"}, {"name": "говяжья печень", "measurement_unit": "шт."}, {"name": "говяжья черева", "measurement_unit": "г"}, {"name": "говяжья шейка", "measurement_unit": "кг"}, {"name": "годжи", "measurement_unit": "г"}, {"name": "голец филе", "measurement_unit": "шт."}, {"name": "голубика", "measurement_unit": "г"}, {"name": "голубика замороженная", "measurement_unit": "г"}, {"name": "голубь", "measurement_unit": "г"}, {"name": "горбуша", "measurement_unit": "по вкусу"}, {"name": "горбуша в собственном соку", "measurement_unit": "банка"}, {"name": "горбуша филе", "measurement_unit": "г"}, {"name": "горгонзола", "measurement_unit": "г"}, {"name": "горгонзола пиканте", "measurement_unit": "г"}, {"name": "горох", "measurement_unit": "г"}, {"name": "горох колотый", "measurement_unit": "г"}, {"name": "гороховые ростки", "measurement_unit": "горсть"}, {"name": "гороховый суп", "measurement_unit": "г"}, {"name": "горошек зеленый", "measurement_unit": "г"}, {"name": "горошек зеленый замороженный", "measurement_unit": "г"}, {"name": "горошек зеленый консервированный", "measurement_unit": "г"}, {"name": "горошек стручковый свежий", "measurement_unit": "г"}, {"name": "горчица", "measurement_unit": "г"}, {"name": "горчица дижонская", "measurement_unit": "г"}, {"name": "горчица дижонская с медом", "measurement_unit": "г"}, {"name": "горчица желтая семена", "measurement_unit": "г"}, {"name": "горчица острая", "measurement_unit": "г"}, {"name": "горчица русская", "measurement_unit": "ст. л."}, {"name": "горчица семена", "measurement_unit": "г"}, {"name": "горчица с зернами", "measurement_unit": "г"}, {"name": "горчица сухая", "measurement_unit": "г"}, {"name": "горчица французская", "measurement_unit": "г"}, {"name": "горчица цитрусовая", "measurement_unit": "г"}, {"name": "горчичное масло", "measurement_unit": "г"}, {"name": "горчичный порошок", "measurement_unit": "г"}, {"name": "грана падано", "measurement_unit": "ст. л."}, {"name": "гранатные зерна", "measurement_unit": "г"}, {"name": "гранатовая паста", "measurement_unit": "ст. л."}, {"name": "гранатовый сироп", "measurement_unit": "г"}, {"name": "гранатовый сок", "measurement_unit": "г"}, {"name": "гранатовый сок свежевыжатый", "measurement_unit": "мл"}, {"name": "гранатовый соус", "measurement_unit": "ч. л."}, {"name": "гранаты", "measurement_unit": "г"}, {"name": "гранита", "measurement_unit": "г"}, {"name": "гранола с орехами", "measurement_unit": "г"}, {"name": "граппа", "measurement_unit": "ч. л."}, {"name": "гратен", "measurement_unit": "кг"}, {"name": "грейпфрутовая цедра", "measurement_unit": "г"}, {"name": "грейпфрутовый сок", "measurement_unit": "г"}, {"name": "грейпфруты", "measurement_unit": "г"}, {"name": "грейпфруты розовые", "measurement_unit": "г"}, {"name": "гренадин", "measurement_unit": "г"}, {"name": "гренки", "measurement_unit": "г"}, {"name": "грецкие орехи", "measurement_unit": "г"}, {"name": "грецкие орехи рубленые", "measurement_unit": "г"}, {"name": "гречневая крупа", "measurement_unit": "г"}, {"name": "гречневая крупа зеленая", "measurement_unit": "ст. л."}, {"name": "гречневая лапша соба", "measurement_unit": "г"}, {"name": "гречневая мука", "measurement_unit": "г"}, {"name": "гречневое молоко", "measurement_unit": "стакан"}, {"name": "гречневые хлопья", "measurement_unit": "г"}, {"name": "грибы", "measurement_unit": "г"}, {"name": "грибы белые", "measurement_unit": "г"}, {"name": "грибы белые замороженные", "measurement_unit": "г"}, {"name": "грибы белые маринованные", "measurement_unit": "г"}, {"name": "грибы белые сухие", "measurement_unit": "г"}, {"name": "грибы замороженные", "measurement_unit": "г"}, {"name": "грибы замороженные (опята и маслята)", "measurement_unit": "г"}, {"name": "грибы лесные", "measurement_unit": "г"}, {"name": "грибы маринованные", "measurement_unit": "г"}, {"name": "грибы свежие", "measurement_unit": "г"}, {"name": "грибы соленые", "measurement_unit": "г"}, {"name": "грибы соломенные консервированные", "measurement_unit": "шт."}, {"name": "грибы сухие", "measurement_unit": "г"}, {"name": "грибы шиитаке", "measurement_unit": "г"}, {"name": "грибы шиитаке сухие", "measurement_unit": "г"}, {"name": "гриль", "measurement_unit": "г"}, {"name": "гриссини", "measurement_unit": "г"}, {"name": "грудинка", "measurement_unit": "г"}, {"name": "грудинка варено-копченая", "measurement_unit": "г"}, {"name": "грудинка копченая", "measurement_unit": "по вкусу"}, {"name": "грушевое пюре", "measurement_unit": "г"}, {"name": "грушевый ликер", "measurement_unit": "мл"}, {"name": "грушевый сироп", "measurement_unit": "мл"}, {"name": "грушевый сок", "measurement_unit": "г"}, {"name": "грушевый уксус", "measurement_unit": "ст. л."}, {"name": "груши", "measurement_unit": "по вкусу"}, {"name": "груши вяленые", "measurement_unit": "г"}, {"name": "грюйер", "measurement_unit": "г"}, {"name": "гуава", "measurement_unit": "шт."}, {"name": "гуанчиале", "measurement_unit": "г"}, {"name": "гурьевская каша", "measurement_unit": "г"}, {"name": "гусиная грудка копченая", "measurement_unit": "г"}, {"name": "гусиная печень", "measurement_unit": "г"}, {"name": "гусиный жир", "measurement_unit": "ст. л."}, {"name": "гусь", "measurement_unit": "г"}, {"name": "гусь тушка", "measurement_unit": "кг"}, {"name": "дайкон", "measurement_unit": "г"}, {"name": "детское питание", "measurement_unit": "г"}, {"name": "джем", "measurement_unit": "г"}, {"name": "джин", "measurement_unit": "г"}, {"name": "джусай", "measurement_unit": "г"}, {"name": "диоксид титана", "measurement_unit": "г"}, {"name": "долма", "measurement_unit": "г"}, {"name": "дорада", "measurement_unit": "шт."}, {"name": "дорада потрошеная с головой", "measurement_unit": "шт."}, {"name": "дорада с головой", "measurement_unit": "шт."}, {"name": "дорада тушка", "measurement_unit": "шт."}, {"name": "драже", "measurement_unit": "г"}, {"name": "дрожжи домашние", "measurement_unit": "г"}, {"name": "дрожжи свежие", "measurement_unit": "г"}, {"name": "дрожжи сухие", "measurement_unit": "по вкусу"}, {"name": "дубовая кора", "measurement_unit": "г"}, {"name": "душица", "measurement_unit": "г"}, {"name": "дыня", "measurement_unit": "г"}, {"name": "ежевика", "measurement_unit": "г"}, {"name": "ежевика замороженная", "measurement_unit": "г"}, {"name": "ерш", "measurement_unit": "г"}, {"name": "ёрш-носарь", "measurement_unit": "шт."}, {"name": "желатин", "measurement_unit": "г"}, {"name": "желатин листовой", "measurement_unit": "по вкусу"}, {"name": "желе", "measurement_unit": "г"}, {"name": "желе для торта", "measurement_unit": "упаковка"}, {"name": "желирующее вещество", "measurement_unit": "упаковка"}, {"name": "желирующий сахар", "measurement_unit": "г"}, {"name": "женьшень", "measurement_unit": "г"}, {"name": "жидкий дым", "measurement_unit": "г"}, {"name": "жимолость", "measurement_unit": "г"}, {"name": "жир", "measurement_unit": "г"}, {"name": "жир вытопленный", "measurement_unit": "стакан"}, {"name": "жир кулинарный", "measurement_unit": "г"}, {"name": "жир растительный", "measurement_unit": "г"}, {"name": "заатар", "measurement_unit": "щепотка"}, {"name": "завтрак сухой", "measurement_unit": "г"}, {"name": "завтрак сухой подушечки", "measurement_unit": "г"}, {"name": "загуститель для сливок", "measurement_unit": "г"}, {"name": "зайчатина", "measurement_unit": "г"}, {"name": "закваска", "measurement_unit": "пакет"}, {"name": "закваска вечная", "measurement_unit": "г"}, {"name": "заменитель сахара", "measurement_unit": "по вкусу"}, {"name": "заменитель сахара стевия", "measurement_unit": "г"}, {"name": "заправка для салатов готовая", "measurement_unit": "г"}, {"name": "зверобой", "measurement_unit": "по вкусу"}, {"name": "зелень", "measurement_unit": "г"}, {"name": "зелень рубленая", "measurement_unit": "г"}, {"name": "земляника", "measurement_unit": "по вкусу"}, {"name": "земляника замороженная", "measurement_unit": "г"}, {"name": "зефир", "measurement_unit": "г"}, {"name": "зира", "measurement_unit": "г"}, {"name": "злаковые хлопья", "measurement_unit": "г"}, {"name": "зубатка", "measurement_unit": "г"}, {"name": "зубатка филе", "measurement_unit": "г"}, {"name": "изолят соевого протеина", "measurement_unit": "г"}, {"name": "изюм", "measurement_unit": "г"}, {"name": "изюм без косточек", "measurement_unit": "г"}, {"name": "изюм белый", "measurement_unit": "г"}, {"name": "изюм черный", "measurement_unit": "г"}, {"name": "икра", "measurement_unit": "г"}, {"name": "икра вяленой рыбы", "measurement_unit": "г"}, {"name": "икра горбуши зернистая", "measurement_unit": "г"}, {"name": "икра красная", "measurement_unit": "г"}, {"name": "икра красной рыбы мелкая", "measurement_unit": "г"}, {"name": "икра летучей рыбы", "measurement_unit": "г"}, {"name": "икра лосося", "measurement_unit": "г"}, {"name": "икра мойвы", "measurement_unit": "г"}, {"name": "икра палтуса", "measurement_unit": "г"}, {"name": "икра судака", "measurement_unit": "г"}, {"name": "икра черная", "measurement_unit": "г"}, {"name": "имбирное варенье", "measurement_unit": "г"}, {"name": "имбирное печенье", "measurement_unit": "по вкусу"}, {"name": "имбирные цукаты", "measurement_unit": "ст. л."}, {"name": "имбирь", "measurement_unit": "г"}, {"name": "имбирь засахаренный", "measurement_unit": "г"}, {"name": "имбирь корень", "measurement_unit": "г"}, {"name": "имбирь маринованный", "measurement_unit": "г"}, {"name": "имбирь молотый", "measurement_unit": "г"}, {"name": "индейка", "measurement_unit": "г"}, {"name": "индейка голень", "measurement_unit": "г"}, {"name": "индейка грудка", "measurement_unit": "г"}, {"name": "индейка копченая", "measurement_unit": "г"}, {"name": "индейка тушка", "measurement_unit": "шт."}, {"name": "индейка фарш", "measurement_unit": "г"}, {"name": "индейка филе", "measurement_unit": "г"}, {"name": "индоутка", "measurement_unit": "шт."}, {"name": "индюшачья печень", "measurement_unit": "г"}, {"name": "инжир", "measurement_unit": "г"}, {"name": "инжир свежий", "measurement_unit": "г"}, {"name": "инжир сушеный", "measurement_unit": "г"}, {"name": "ирга", "measurement_unit": "г"}, {"name": "ириски", "measurement_unit": "г"}, {"name": "итальянские травы", "measurement_unit": "г"}, {"name": "йогурт", "measurement_unit": "г"}, {"name": "йогурт греческий", "measurement_unit": "г"}, {"name": "йогурт жирный", "measurement_unit": "г"}, {"name": "йогурт козий", "measurement_unit": "г"}, {"name": "йогурт натуральный", "measurement_unit": "г"}, {"name": "йогурт нежирный", "measurement_unit": "г"}, {"name": "йогурт обезжиренный", "measurement_unit": "г"}, {"name": "йогурт фруктовый", "measurement_unit": "г"}, {"name": "кабачки", "measurement_unit": "г"}, {"name": "кабачки замороженные", "measurement_unit": "г"}, {"name": "кабачки молодые", "measurement_unit": "г"}, {"name": "каджунская смесь специй", "measurement_unit": "ст. л."}, {"name": "какао", "measurement_unit": "горсть"}, {"name": "какао-бобы", "measurement_unit": "г"}, {"name": "какао-масло", "measurement_unit": "г"}, {"name": "какао-порошок", "measurement_unit": "по вкусу"}, {"name": "какао-порошок обезжиренный", "measurement_unit": "г"}, {"name": "какао сгущенное", "measurement_unit": "банка"}, {"name": "калина", "measurement_unit": "по вкусу"}, {"name": "калина протертая", "measurement_unit": "г"}, {"name": "калинджи семена", "measurement_unit": "ч. л."}, {"name": "кальвадос", "measurement_unit": "г"}, {"name": "кальмары", "measurement_unit": "г"}, {"name": "кальмары вареные", "measurement_unit": "г"}, {"name": "кальмары замороженные", "measurement_unit": "г"}, {"name": "кальмары консервированные", "measurement_unit": "г"}, {"name": "кальмары филе", "measurement_unit": "шт."}, {"name": "камамбер", "measurement_unit": "упаковка"}, {"name": "камбала", "measurement_unit": "г"}, {"name": "камбала филе", "measurement_unit": "г"}, {"name": "кампари", "measurement_unit": "мл"}, {"name": "кандурин золотой", "measurement_unit": "ч. л."}, {"name": "каннеллони", "measurement_unit": "г"}, {"name": "капеллини", "measurement_unit": "г"}, {"name": "каперсы", "measurement_unit": "г"}, {"name": "каперсы в винном уксусе", "measurement_unit": "г"}, {"name": "каперсы маринованные", "measurement_unit": "г"}, {"name": "капуста белокочанная", "measurement_unit": "г"}, {"name": "капуста брюссельская", "measurement_unit": "г"}, {"name": "капуста брюссельская замороженная", "measurement_unit": "г"}, {"name": "капуста кале", "measurement_unit": "г"}, {"name": "капуста квашеная", "measurement_unit": "по вкусу"}, {"name": "капуста кольраби", "measurement_unit": "г"}, {"name": "капуста краснокочанная", "measurement_unit": "г"}, {"name": "капуста морская", "measurement_unit": "по вкусу"}, {"name": "капуста морская замороженная", "measurement_unit": "г"}, {"name": "капуста морская сушеная", "measurement_unit": "г"}, {"name": "капуста пекинская", "measurement_unit": "г"}, {"name": "капуста савойская", "measurement_unit": "г"}, {"name": "капуста цветная", "measurement_unit": "г"}, {"name": "капуста цветная замороженная", "measurement_unit": "г"}, {"name": "капустный рассол", "measurement_unit": "г"}, {"name": "капучино", "measurement_unit": "г"}, {"name": "каракатица", "measurement_unit": "г"}, {"name": "каракатица очищенная", "measurement_unit": "г"}, {"name": "карамбола", "measurement_unit": "г"}, {"name": "карамель", "measurement_unit": "мл"}, {"name": "карамельный соус", "measurement_unit": "г"}, {"name": "карамель с начинкой", "measurement_unit": "г"}, {"name": "карамель соленая", "measurement_unit": "г"}, {"name": "карась", "measurement_unit": "г"}, {"name": "карбонад", "measurement_unit": "г"}, {"name": "кардамон", "measurement_unit": "г"}, {"name": "кардамон зерна", "measurement_unit": "ч. л."}, {"name": "кардамон молотый", "measurement_unit": "г"}, {"name": "кардамон стручки", "measurement_unit": "шт."}, {"name": "каркаде", "measurement_unit": "г"}, {"name": "карп", "measurement_unit": "г"}, {"name": "карп зеркальный", "measurement_unit": "кг"}, {"name": "карп филе", "measurement_unit": "кг"}, {"name": "карри", "measurement_unit": "г"}, {"name": "карри листья", "measurement_unit": "г"}, {"name": "карри паста", "measurement_unit": "пакет"}, {"name": "картофель", "measurement_unit": "г"}, {"name": "картофель вареный", "measurement_unit": "г"}, {"name": "картофель вареный в мундире", "measurement_unit": "г"}, {"name": "картофель молодой", "measurement_unit": "г"}, {"name": "картофельное пюре", "measurement_unit": "по вкусу"}, {"name": "картофельные ньокки", "measurement_unit": "г"}, {"name": "картофельные хлопья", "measurement_unit": "г"}, {"name": "картофельные чипсы", "measurement_unit": "г"}, {"name": "картофельный крахмал", "measurement_unit": "г"}, {"name": "картофельный отвар", "measurement_unit": "г"}, {"name": "картофельный хэш замороженный", "measurement_unit": "г"}, {"name": "картофель печеный", "measurement_unit": "г"}, {"name": "катык", "measurement_unit": "г"}, {"name": "каффир-лайм листья", "measurement_unit": "по вкусу"}, {"name": "каша", "measurement_unit": "г"}, {"name": "каша для детского питания", "measurement_unit": "г"}, {"name": "каштановая мука", "measurement_unit": "г"}, {"name": "каштановый крем", "measurement_unit": "г"}, {"name": "каштаны", "measurement_unit": "г"}, {"name": "каштаны вареные", "measurement_unit": "г"}, {"name": "каштаны консервированные", "measurement_unit": "г"}, {"name": "каштаны очищенные", "measurement_unit": "г"}, {"name": "квас", "measurement_unit": "г"}, {"name": "квасное сусло", "measurement_unit": "г"}, {"name": "квасной концентрат сухой", "measurement_unit": "упаковка"}, {"name": "квас хлебный", "measurement_unit": "г"}, {"name": "кедровая мука", "measurement_unit": "г"}, {"name": "кедровые орехи", "measurement_unit": "г"}, {"name": "кедровые орехи жареные", "measurement_unit": "г"}, {"name": "кета", "measurement_unit": "г"}, {"name": "кетчуп острый", "measurement_unit": "по вкусу"}, {"name": "кетчуп томатный", "measurement_unit": "г"}, {"name": "кетчуп тосканский", "measurement_unit": "ст. л."}, {"name": "кетчуп шашлычный", "measurement_unit": "г"}, {"name": "кефаль", "measurement_unit": "г"}, {"name": "кефир", "measurement_unit": "по вкусу"}, {"name": "кефир 1%", "measurement_unit": "г"}, {"name": "кефир 2,5%", "measurement_unit": "г"}, {"name": "кефир 3,2%", "measurement_unit": "г"}, {"name": "кефир обезжиренный", "measurement_unit": "г"}, {"name": "кешью", "measurement_unit": "г"}, {"name": "кивано", "measurement_unit": "г"}, {"name": "киви", "measurement_unit": "кг"}, {"name": "киви желе", "measurement_unit": "г"}, {"name": "кижуч", "measurement_unit": "г"}, {"name": "кижуч горячего копчения филе", "measurement_unit": "г"}, {"name": "кизил", "measurement_unit": "г"}, {"name": "килька", "measurement_unit": "г"}, {"name": "кимчи", "measurement_unit": "г"}, {"name": "кинза свежая", "measurement_unit": "зубчик"}, {"name": "кинза сушеная", "measurement_unit": "г"}, {"name": "киноа", "measurement_unit": "г"}, {"name": "киноа молотая", "measurement_unit": "г"}, {"name": "кипяток", "measurement_unit": "г"}, {"name": "кирш", "measurement_unit": "ст. л."}, {"name": "кисель", "measurement_unit": "г"}, {"name": "кисель сухой", "measurement_unit": "г"}, {"name": "кисломолочный напиток Тан", "measurement_unit": "мл"}, {"name": "кишки", "measurement_unit": "г"}, {"name": "клейковина", "measurement_unit": "г"}, {"name": "клементины", "measurement_unit": "г"}, {"name": "кленовый сироп", "measurement_unit": "г"}, {"name": "клубника", "measurement_unit": "г"}, {"name": "клубника в сиропе", "measurement_unit": "г"}, {"name": "клубника замороженная", "measurement_unit": "г"}, {"name": "клубника, протертая с сахаром", "measurement_unit": "г"}, {"name": "клубника сушеная", "measurement_unit": "г"}, {"name": "клубничное варенье", "measurement_unit": "г"}, {"name": "клубничное желе", "measurement_unit": "упаковка"}, {"name": "клубничное пюре", "measurement_unit": "г"}, {"name": "клубничный джем", "measurement_unit": "г"}, {"name": "клубничный джем густой", "measurement_unit": "мл"}, {"name": "клубничный компот", "measurement_unit": "стакан"}, {"name": "клубничный ликер", "measurement_unit": "г"}, {"name": "клубничный сироп", "measurement_unit": "г"}, {"name": "клюква", "measurement_unit": "г"}, {"name": "клюква вяленая", "measurement_unit": "г"}, {"name": "клюква замороженная", "measurement_unit": "г"}, {"name": "клюква, протертая с сахаром", "measurement_unit": "г"}, {"name": "клюквенное варенье", "measurement_unit": "г"}, {"name": "клюквенный джем", "measurement_unit": "г"}, {"name": "клюквенный морс", "measurement_unit": "ст. л."}, {"name": "клюквенный сироп", "measurement_unit": "г"}, {"name": "клюквенный соус", "measurement_unit": "г"}, {"name": "козлиная печень", "measurement_unit": "г"}, {"name": "козлятина молодая", "measurement_unit": "кг"}, {"name": "кока-кола", "measurement_unit": "ст. л."}, {"name": "кокосовая вода", "measurement_unit": "стакан"}, {"name": "кокосовая мука", "measurement_unit": "ст. л."}, {"name": "кокосовая стружка", "measurement_unit": "г"}, {"name": "кокосовая стружка цветная", "measurement_unit": "г"}, {"name": "кокосовое масло", "measurement_unit": "мл"}, {"name": "кокосовое молоко", "measurement_unit": "г"}, {"name": "кокосовые сливки", "measurement_unit": "г"}, {"name": "кокосовый ликер", "measurement_unit": "ст. л."}, {"name": "кокосовый экстракт", "measurement_unit": "г"}, {"name": "кокосы", "measurement_unit": "г"}, {"name": "кола", "measurement_unit": "г"}, {"name": "колбаса", "measurement_unit": "г"}, {"name": "колбаса вареная", "measurement_unit": "г"}, {"name": "колбаса варено-копченая", "measurement_unit": "г"}, {"name": "колбаса копченая", "measurement_unit": "г"}, {"name": "колбаса кровяная", "measurement_unit": "г"}, {"name": "колбаса полукопченая", "measurement_unit": "г"}, {"name": "колбаса сырокопченая", "measurement_unit": "г"}, {"name": "колбаска свиная свежая (salsiccia)", "measurement_unit": "шт."}, {"name": "колбаски", "measurement_unit": "г"}, {"name": "колбаски для жарки", "measurement_unit": "г"}, {"name": "колбаски домашние", "measurement_unit": "шт."}, {"name": "колбаски охотничьи", "measurement_unit": "г"}, {"name": "колбаски сырокопченые", "measurement_unit": "шт."}, {"name": "компот", "measurement_unit": "г"}, {"name": "конопляное масло", "measurement_unit": "ст. л."}, {"name": "конопля семена", "measurement_unit": "г"}, {"name": "конфеты", "measurement_unit": "по вкусу"}, {"name": "конфеты M&M’s", "measurement_unit": "г"}, {"name": "конфеты жевательные лакричные", "measurement_unit": "г"}, {"name": "конфеты Коровка", "measurement_unit": "г"}, {"name": "конфеты Трюфель", "measurement_unit": "г"}, {"name": "конфитюр", "measurement_unit": "по вкусу"}, {"name": "конфитюрка", "measurement_unit": "упаковка"}, {"name": "коньяк", "measurement_unit": "г"}, {"name": "копчености", "measurement_unit": "г"}, {"name": "коренья", "measurement_unit": "по вкусу"}, {"name": "кориандр", "measurement_unit": "г"}, {"name": "кориандр зелень", "measurement_unit": "г"}, {"name": "кориандр молотый", "measurement_unit": "г"}, {"name": "кориандр семена", "measurement_unit": "г"}, {"name": "коринка", "measurement_unit": "ст. л."}, {"name": "корица", "measurement_unit": "г"}, {"name": "корица молотая", "measurement_unit": "г"}, {"name": "корнишоны", "measurement_unit": "г"}, {"name": "корнишоны маринованые", "measurement_unit": "г"}, {"name": "корюшка", "measurement_unit": "г"}, {"name": "корюшка горячего копчения", "measurement_unit": "г"}, {"name": "кости", "measurement_unit": "г"}, {"name": "кости мозговые", "measurement_unit": "г"}, {"name": "кость сахарная", "measurement_unit": "г"}, {"name": "кофе в зернах", "measurement_unit": "стакан"}, {"name": "кофе зеленый", "measurement_unit": "г"}, {"name": "кофейные зерна в шоколаде", "measurement_unit": "г"}, {"name": "кофейный ликер", "measurement_unit": "г"}, {"name": "кофейный ликер Kahlua", "measurement_unit": "мл"}, {"name": "кофейный напиток", "measurement_unit": "мл"}, {"name": "кофейный сироп", "measurement_unit": "г"}, {"name": "кофейный экстракт", "measurement_unit": "мл"}, {"name": "кофе молотый", "measurement_unit": "ст. л."}, {"name": "кофе растворимый", "measurement_unit": "г"}, {"name": "кофе свежесваренный", "measurement_unit": "г"}, {"name": "кофе черный", "measurement_unit": "г"}, {"name": "кофе эспрессо", "measurement_unit": "стакан"}, {"name": "крабовое мясо", "measurement_unit": "г"}, {"name": "крабовые палочки", "measurement_unit": "по вкусу"}, {"name": "краб снежный", "measurement_unit": "по вкусу"}, {"name": "крабы", "measurement_unit": "г"}, {"name": "крапива", "measurement_unit": "г"}, {"name": "краситель-гель пищевой", "measurement_unit": "шт."}, {"name": "краситель пищевой", "measurement_unit": "г"}, {"name": "краситель пищевой вишневый", "measurement_unit": "щепотка"}, {"name": "краситель пищевой желтый", "measurement_unit": "г"}, {"name": "краситель пищевой зеленый", "measurement_unit": "ст. л."}, {"name": "краситель пищевой красный", "measurement_unit": "г"}, {"name": "краситель пищевой оранжевый", "measurement_unit": "г"}, {"name": "краситель пищевой фиолетовый", "measurement_unit": "г"}, {"name": "краситель пищевой черный", "measurement_unit": "г"}, {"name": "красная смородина", "measurement_unit": "г"}, {"name": "красная смородина, протертая с сахаром", "measurement_unit": "ст. л."}, {"name": "красноперка", "measurement_unit": "шт."}, {"name": "красносмородиновое варенье", "measurement_unit": "г"}, {"name": "красный винный соус", "measurement_unit": "г"}, {"name": "крахмал", "measurement_unit": "г"}, {"name": "креветки", "measurement_unit": "г"}, {"name": "креветки замороженные", "measurement_unit": "г"}, {"name": "креветки королевские", "measurement_unit": "г"}, {"name": "креветки очищенные", "measurement_unit": "г"}, {"name": "креветки очищенные в рассоле", "measurement_unit": "г"}, {"name": "креветки салатные", "measurement_unit": "г"}, {"name": "креветки сушеные", "measurement_unit": "г"}, {"name": "креветки тигровые", "measurement_unit": "г"}, {"name": "крекер", "measurement_unit": "г"}, {"name": "крекер соленый", "measurement_unit": "г"}, {"name": "крем заварной", "measurement_unit": "г"}, {"name": "крем заварной порошковый", "measurement_unit": "г"}, {"name": "крем-фреш", "measurement_unit": "г"}, {"name": "кресс-салат", "measurement_unit": "г"}, {"name": "кровь", "measurement_unit": "мл"}, {"name": "кролик", "measurement_unit": "г"}, {"name": "кролик тушка", "measurement_unit": "г"}, {"name": "кролик филе", "measurement_unit": "г"}, {"name": "кроличья печень", "measurement_unit": "г"}, {"name": "круассаны", "measurement_unit": "по вкусу"}, {"name": "крутоны мелкие", "measurement_unit": "г"}, {"name": "крыжовник", "measurement_unit": "г"}, {"name": "крыжовниковое варенье", "measurement_unit": "банка"}, {"name": "кукуруза", "measurement_unit": "г"}, {"name": "кукуруза замороженная", "measurement_unit": "г"}, {"name": "кукуруза консервированная", "measurement_unit": "г"}, {"name": "кукуруза обжаренная кикос", "measurement_unit": "г"}, {"name": "кукурузная крупа", "measurement_unit": "г"}, {"name": "кукурузная мука", "measurement_unit": "г"}, {"name": "кукурузное масло", "measurement_unit": "г"}, {"name": "кукурузные лепешки", "measurement_unit": "шт."}, {"name": "кукурузные палочки", "measurement_unit": "г"}, {"name": "кукурузные хлопья", "measurement_unit": "г"}, {"name": "кукурузные хлопья глазированные", "measurement_unit": "г"}, {"name": "кукурузные чипсы", "measurement_unit": "г"}, {"name": "кукурузный (золотой) сироп", "measurement_unit": "г"}, {"name": "кукурузный крахмал", "measurement_unit": "по вкусу"}, {"name": "кумин", "measurement_unit": "г"}, {"name": "кумкваты", "measurement_unit": "горсть"}, {"name": "кунжут", "measurement_unit": "г"}, {"name": "кунжутная мука", "measurement_unit": "г"}, {"name": "кунжутная паста", "measurement_unit": "г"}, {"name": "кунжутное масло", "measurement_unit": "г"}, {"name": "кунжутные семечки", "measurement_unit": "по вкусу"}, {"name": "кунжут черный", "measurement_unit": "ч. л."}, {"name": "купаты", "measurement_unit": "шт."}, {"name": "курага", "measurement_unit": "по вкусу"}, {"name": "курдючное сало", "measurement_unit": "г"}, {"name": "курдючный жир", "measurement_unit": "г"}, {"name": "куриная ветчина", "measurement_unit": "г"}, {"name": "куриная кожа", "measurement_unit": "г"}, {"name": "куриная печень", "measurement_unit": "г"}, {"name": "куриное карпаччо", "measurement_unit": "г"}, {"name": "куриное филе", "measurement_unit": "г"}, {"name": "куриные бедра", "measurement_unit": "г"}, {"name": "куриные голени", "measurement_unit": "г"}, {"name": "куриные голени копченые", "measurement_unit": "шт."}, {"name": "куриные грудки", "measurement_unit": "г"}, {"name": "куриные грудки вареные", "measurement_unit": "г"}, {"name": "куриные грудки копченые", "measurement_unit": "г"}, {"name": "куриные желудочки", "measurement_unit": "шт."}, {"name": "куриные кости", "measurement_unit": "г"}, {"name": "куриные крылья", "measurement_unit": "г"}, {"name": "куриные окорочка", "measurement_unit": "г"}, {"name": "куриные окорочка копченые", "measurement_unit": "г"}, {"name": "куриные потрошки", "measurement_unit": "г"}, {"name": "куриные сердечки", "measurement_unit": "г"}, {"name": "куриный бульон", "measurement_unit": "г"}, {"name": "куриный паштет", "measurement_unit": "г"}, {"name": "куриный суповой набор", "measurement_unit": "кг"}, {"name": "куриный фарш", "measurement_unit": "г"}, {"name": "курица", "measurement_unit": "г"}, {"name": "курица вареная", "measurement_unit": "г"}, {"name": "курица для жарки", "measurement_unit": "кг"}, {"name": "курица копченая", "measurement_unit": "г"}, {"name": "курица тушка", "measurement_unit": "г"}, {"name": "куркума", "measurement_unit": "г"}, {"name": "куропатки", "measurement_unit": "г"}, {"name": "кускус", "measurement_unit": "г"}, {"name": "кускус жемчужный", "measurement_unit": "стакан"}, {"name": "кэроб", "measurement_unit": "г"}, {"name": "лаванда", "measurement_unit": "г"}, {"name": "лаванда сушеная", "measurement_unit": "щепотка"}, {"name": "лавандовый краситель", "measurement_unit": "ч. л."}, {"name": "лаваш", "measurement_unit": "по вкусу"}, {"name": "лаваш армянский", "measurement_unit": "г"}, {"name": "лаваш персидский круглый", "measurement_unit": "г"}, {"name": "лаваш тонкий", "measurement_unit": "пласт"}, {"name": "лавровые листья свежие", "measurement_unit": "шт."}, {"name": "лавровый лист", "measurement_unit": "г"}, {"name": "лайм", "measurement_unit": "г"}, {"name": "лайм листья", "measurement_unit": "шт."}, {"name": "лаймовая цедра", "measurement_unit": "г"}, {"name": "лаймовый сок", "measurement_unit": "г"}, {"name": "лангустины", "measurement_unit": "шт."}, {"name": "лапша", "measurement_unit": "г"}, {"name": "лапша для лагмана", "measurement_unit": "упаковка"}, {"name": "лапша ширатаки", "measurement_unit": "г"}, {"name": "лапша яичная в гнездах", "measurement_unit": "шт."}, {"name": "латук", "measurement_unit": "г"}, {"name": "легкие", "measurement_unit": "г"}, {"name": "лед", "measurement_unit": "г"}, {"name": "леди-фиш тушка", "measurement_unit": "шт."}, {"name": "лемонграсс (лимонное сорго)", "measurement_unit": "г"}, {"name": "лен семена", "measurement_unit": "г"}, {"name": "лепешки", "measurement_unit": "г"}, {"name": "лепешки арабские", "measurement_unit": "шт."}, {"name": "лесные орехи", "measurement_unit": "г"}, {"name": "лечо", "measurement_unit": "г"}, {"name": "ливер", "measurement_unit": "г"}, {"name": "ликер", "measurement_unit": "г"}, {"name": "ликер Alchermes", "measurement_unit": "г"}, {"name": "ликер Amaretto", "measurement_unit": "г"}, {"name": "ликер Baileys", "measurement_unit": "г"}, {"name": "ликер Cointreau", "measurement_unit": "г"}, {"name": "ликер кремовый", "measurement_unit": "г"}, {"name": "ликер сливочный", "measurement_unit": "г"}, {"name": "лимонад", "measurement_unit": "г"}, {"name": "лимонная кислота", "measurement_unit": "г"}, {"name": "лимонная цедра", "measurement_unit": "г"}, {"name": "лимонник стебель", "measurement_unit": "г"}, {"name": "лимонник ягоды", "measurement_unit": "г"}, {"name": "лимонные корочки засахаренные", "measurement_unit": "г"}, {"name": "лимонные цукаты", "measurement_unit": "г"}, {"name": "лимонный сок", "measurement_unit": "г"}, {"name": "лимонный уксус", "measurement_unit": "г"}, {"name": "лимонный экстракт", "measurement_unit": "г"}, {"name": "лимончелло", "measurement_unit": "г"}, {"name": "лимоны", "measurement_unit": "г"}, {"name": "лингвине", "measurement_unit": "шт."}, {"name": "лисички", "measurement_unit": "г"}, {"name": "лисички сушеные", "measurement_unit": "г"}, {"name": "личи", "measurement_unit": "шт."}, {"name": "личи компот", "measurement_unit": "г"}, {"name": "лобстер", "measurement_unit": "г"}, {"name": "лонган", "measurement_unit": "г"}, {"name": "лонгконг", "measurement_unit": "шт."}, {"name": "лососевые молоки", "measurement_unit": "г"}, {"name": "лососевый фарш", "measurement_unit": "г"}, {"name": "лосось", "measurement_unit": "г"}, {"name": "лосось горячего копчения", "measurement_unit": "г"}, {"name": "лосось копченый", "measurement_unit": "г"}, {"name": "лосось свежесоленый", "measurement_unit": "г"}, {"name": "лосось свежий", "measurement_unit": "г"}, {"name": "лосось свежий филе", "measurement_unit": "г"}, {"name": "лосось слабосоленый", "measurement_unit": "г"}, {"name": "лосось стейки", "measurement_unit": "г"}, {"name": "лосось филе", "measurement_unit": "г"}, {"name": "лосось филе на коже", "measurement_unit": "г"}, {"name": "лосось холодного копчения", "measurement_unit": "г"}, {"name": "лосятина", "measurement_unit": "кг"}, {"name": "лук белый", "measurement_unit": "по вкусу"}, {"name": "лук зеленый", "measurement_unit": "г"}, {"name": "лук красный", "measurement_unit": "по вкусу"}, {"name": "лук маринованный", "measurement_unit": "г"}, {"name": "луковая шелуха", "measurement_unit": "г"}, {"name": "луковый порошок", "measurement_unit": "г"}, {"name": "лук-порей", "measurement_unit": "горсть"}, {"name": "лук-резанец", "measurement_unit": "по вкусу"}, {"name": "лук репчатый", "measurement_unit": "г"}, {"name": "лук репчатый мелкий", "measurement_unit": "г"}, {"name": "лук салатный", "measurement_unit": "шт."}, {"name": "лук сушеный", "measurement_unit": "г"}, {"name": "лук-шалот", "measurement_unit": "г"}, {"name": "лук-шалот красный", "measurement_unit": "шт."}, {"name": "льняная мука", "measurement_unit": "г"}, {"name": "льняное масло", "measurement_unit": "ч. л."}, {"name": "льняное семя", "measurement_unit": "г"}, {"name": "льняное семя молотое", "measurement_unit": "г"}, {"name": "любисток", "measurement_unit": "г"}, {"name": "маасдам", "measurement_unit": "г"}, {"name": "мадера", "measurement_unit": "г"}, {"name": "майонез", "measurement_unit": "г"}, {"name": "майонез домашний", "measurement_unit": "г"}, {"name": "майонез легкий", "measurement_unit": "г"}, {"name": "майонезный соус «Слобода» Постный", "measurement_unit": "г"}, {"name": "майонез оливковый", "measurement_unit": "г"}, {"name": "майонез «Слобода» Легкий", "measurement_unit": "г"}, {"name": "майонез «Слобода» На перепелиных яйцах", "measurement_unit": "г"}, {"name": "майонез «Слобода» Оливковый", "measurement_unit": "г"}, {"name": "майонез «Слобода» Провансаль", "measurement_unit": "г"}, {"name": "майонез «Слобода» С лимонным соком", "measurement_unit": "г"}, {"name": "майонез «Слобода» Сметанный", "measurement_unit": "г"}, {"name": "майоран", "measurement_unit": "г"}, {"name": "майоран свежий", "measurement_unit": "по вкусу"}, {"name": "майоран сушеный", "measurement_unit": "г"}, {"name": "мак", "measurement_unit": "г"}, {"name": "макаронные изделия", "measurement_unit": "г"}, {"name": "макаронные изделия мелкие", "measurement_unit": "г"}, {"name": "макароны", "measurement_unit": "г"}, {"name": "макароны-бабочки (farfalle)", "measurement_unit": "г"}, {"name": "макароны-бабочки (farfalle) мини", "measurement_unit": "г"}, {"name": "макароны баветте", "measurement_unit": "г"}, {"name": "макароны-бантики", "measurement_unit": "г"}, {"name": "макароны букатини", "measurement_unit": "г"}, {"name": "макароны джильи", "measurement_unit": "г"}, {"name": "макароны диталони", "measurement_unit": "г"}, {"name": "макароны-звездочки", "measurement_unit": "стакан"}, {"name": "макароны орзо", "measurement_unit": "г"}, {"name": "макароны-ракушки (conchiglie)", "measurement_unit": "г"}, {"name": "макароны-ракушки (conchiglie rigate)", "measurement_unit": "г"}, {"name": "макароны-ракушки крупные", "measurement_unit": "г"}, {"name": "макароны рисони", "measurement_unit": "г"}, {"name": "макароны-рожки (pipe rigate)", "measurement_unit": "г"}, {"name": "макароны-спиральки (fusilli)", "measurement_unit": "г"}, {"name": "макароны-ушки (orecchiette)", "measurement_unit": "г"}, {"name": "маккерончини", "measurement_unit": "г"}, {"name": "мак молотый", "measurement_unit": "г"}, {"name": "маковая масса", "measurement_unit": "пачка"}, {"name": "малина", "measurement_unit": "г"}, {"name": "малина замороженная", "measurement_unit": "г"}, {"name": "малина, протертая с сахаром", "measurement_unit": "стакан"}, {"name": "малина сушеная", "measurement_unit": "г"}, {"name": "малиновое варенье", "measurement_unit": "г"}, {"name": "малиновое желе", "measurement_unit": "г"}, {"name": "малиновое пюре", "measurement_unit": "г"}, {"name": "малиновый джем", "measurement_unit": "г"}, {"name": "малиновый крем", "measurement_unit": "г"}, {"name": "малиновый сироп", "measurement_unit": "ч. л."}, {"name": "малиновый соус", "measurement_unit": "ч. л."}, {"name": "малиновый уксус", "measurement_unit": "мл"}, {"name": "малиновый чай", "measurement_unit": "г"}, {"name": "манго", "measurement_unit": "по вкусу"}, {"name": "манговый сироп", "measurement_unit": "мл"}, {"name": "манго консервированное", "measurement_unit": "г"}, {"name": "мангольд", "measurement_unit": "г"}, {"name": "мангустин", "measurement_unit": "шт."}, {"name": "мандариновое пюре", "measurement_unit": "г"}, {"name": "мандариновые цукаты", "measurement_unit": "г"}, {"name": "мандариновый сок", "measurement_unit": "г"}, {"name": "мандарины", "measurement_unit": "по вкусу"}, {"name": "мандарины в собственном соку", "measurement_unit": "г"}, {"name": "манная крупа", "measurement_unit": "г"}, {"name": "маракуйя", "measurement_unit": "г"}, {"name": "маргарин", "measurement_unit": "г"}, {"name": "маргарин сливочный", "measurement_unit": "г"}, {"name": "мармелад", "measurement_unit": "по вкусу"}, {"name": "мармелад бутербродный", "measurement_unit": "г"}, {"name": "марсала", "measurement_unit": "стакан"}, {"name": "мартини", "measurement_unit": "г"}, {"name": "мартини красный", "measurement_unit": "г"}, {"name": "марципан", "measurement_unit": "по вкусу"}, {"name": "марципан зеленый", "measurement_unit": "г"}, {"name": "марципан розовый", "measurement_unit": "г"}, {"name": "маршмеллоу", "measurement_unit": "г"}, {"name": "маршмеллоу крем", "measurement_unit": "г"}, {"name": "маршмеллоу мини", "measurement_unit": "г"}, {"name": "маскарпоне", "measurement_unit": "г"}, {"name": "маслины", "measurement_unit": "г"}, {"name": "маслины без косточек", "measurement_unit": "г"}, {"name": "масло авокадо", "measurement_unit": "г"}, {"name": "масло виноградных косточек", "measurement_unit": "г"}, {"name": "масло грецкого ореха", "measurement_unit": "ч. л."}, {"name": "масло для фритюра", "measurement_unit": "г"}, {"name": "масло кедрового ореха", "measurement_unit": "г"}, {"name": "маслята", "measurement_unit": "г"}, {"name": "мастика", "measurement_unit": "г"}, {"name": "мастика желатиновая", "measurement_unit": "г"}, {"name": "мастика шоколадная", "measurement_unit": "г"}, {"name": "матча", "measurement_unit": "г"}, {"name": "мафальдине", "measurement_unit": "г"}, {"name": "маца", "measurement_unit": "г"}, {"name": "мацони", "measurement_unit": "г"}, {"name": "маш", "measurement_unit": "г"}, {"name": "мед", "measurement_unit": "г"}, {"name": "мед акации", "measurement_unit": "г"}, {"name": "мед гречишный", "measurement_unit": "г"}, {"name": "мед жидкий", "measurement_unit": "г"}, {"name": "мед лавандовый", "measurement_unit": "г"}, {"name": "мелисса", "measurement_unit": "г"}, {"name": "меренги", "measurement_unit": "шт."}, {"name": "мидии", "measurement_unit": "г"}, {"name": "мидии в раковинах", "measurement_unit": "г"}, {"name": "мидии в раковинах крупные черные", "measurement_unit": "г"}, {"name": "мидии в раковинах мелкие зеленые", "measurement_unit": "г"}, {"name": "мидии замороженные", "measurement_unit": "шт."}, {"name": "мидии копченые в масле", "measurement_unit": "г"}, {"name": "микрозелень", "measurement_unit": "горсть"}, {"name": "миндаль", "measurement_unit": "г"}, {"name": "миндаль жареный", "measurement_unit": "г"}, {"name": "миндаль измельченный", "measurement_unit": "г"}, {"name": "миндальная масса", "measurement_unit": "г"}, {"name": "миндальная мука", "measurement_unit": "г"}, {"name": "миндальная паста", "measurement_unit": "г"}, {"name": "миндальная эссенция", "measurement_unit": "г"}, {"name": "миндальное масло", "measurement_unit": "г"}, {"name": "миндальное молоко", "measurement_unit": "г"}, {"name": "миндальное печенье", "measurement_unit": "г"}, {"name": "миндальное пралине", "measurement_unit": "г"}, {"name": "миндальные лепестки", "measurement_unit": "г"}, {"name": "миндальный ликер", "measurement_unit": "г"}, {"name": "миндальный сироп", "measurement_unit": "г"}, {"name": "миндальный экстракт", "measurement_unit": "капля"}, {"name": "миндаль очищенный", "measurement_unit": "г"}, {"name": "миндаль рубленый", "measurement_unit": "г"}, {"name": "мини-кукуруза", "measurement_unit": "шт."}, {"name": "минога", "measurement_unit": "г"}, {"name": "минтай", "measurement_unit": "г"}, {"name": "минтай печень", "measurement_unit": "г"}, {"name": "минтай филе", "measurement_unit": "г"}, {"name": "мисо-паста", "measurement_unit": "г"}, {"name": "мисо-суп", "measurement_unit": "пакет"}, {"name": "можжевельник ягоды", "measurement_unit": "г"}, {"name": "мойва", "measurement_unit": "г"}, {"name": "моллюски", "measurement_unit": "г"}, {"name": "молоко", "measurement_unit": "г"}, {"name": "молоко 0,5%", "measurement_unit": "г"}, {"name": "молоко 1,5%", "measurement_unit": "г"}, {"name": "молоко 2,5%", "measurement_unit": "г"}, {"name": "молоко 3,2%", "measurement_unit": "г"}, {"name": "молоко 3,6%", "measurement_unit": "г"}, {"name": "молоко 4%", "measurement_unit": "г"}, {"name": "молоко 6%", "measurement_unit": "г"}, {"name": "молоко козье", "measurement_unit": "г"}, {"name": "молоко концентрированное", "measurement_unit": "г"}, {"name": "молоко рисовое", "measurement_unit": "мл"}, {"name": "молоко сгущенное", "measurement_unit": "г"}, {"name": "молоко сгущенное вареное", "measurement_unit": "ст. л."}, {"name": "молоко сгущенное с какао", "measurement_unit": "г"}, {"name": "молоко сухое", "measurement_unit": "г"}, {"name": "молоко сухое обезжиренное", "measurement_unit": "ст. л."}, {"name": "молоко топленое", "measurement_unit": "г"}, {"name": "молочная смесь", "measurement_unit": "г"}, {"name": "молочные продукты", "measurement_unit": "г"}, {"name": "морепродукты", "measurement_unit": "шт."}, {"name": "морковное пюре", "measurement_unit": "г"}, {"name": "морковь", "measurement_unit": "г"}, {"name": "морковь вареная", "measurement_unit": "г"}, {"name": "морковь крупная", "measurement_unit": "г"}, {"name": "морковь молодая", "measurement_unit": "г"}, {"name": "морковь по-корейски", "measurement_unit": "г"}, {"name": "морковь тертая", "measurement_unit": "шт."}, {"name": "мороженое", "measurement_unit": "по вкусу"}, {"name": "мороженое ванильное", "measurement_unit": "г"}, {"name": "мороженое клубничное", "measurement_unit": "г"}, {"name": "мороженое лимонное", "measurement_unit": "по вкусу"}, {"name": "мороженое малиновое", "measurement_unit": "г"}, {"name": "мороженое пломбир", "measurement_unit": "г"}, {"name": "мороженое шоколадное", "measurement_unit": "мл"}, {"name": "морошка", "measurement_unit": "г"}, {"name": "морские гребешки", "measurement_unit": "кг"}, {"name": "морской коктейль", "measurement_unit": "г"}, {"name": "морской коктейль в масле", "measurement_unit": "упаковка"}, {"name": "морской коктейль замороженный", "measurement_unit": "г"}, {"name": "морской черт", "measurement_unit": "г"}, {"name": "морской язык", "measurement_unit": "г"}, {"name": "морской язык филе", "measurement_unit": "г"}, {"name": "мортаделла", "measurement_unit": "г"}, {"name": "моцарелла", "measurement_unit": "г"}, {"name": "моцарелла для запекания", "measurement_unit": "г"}, {"name": "моцарелла для пиццы", "measurement_unit": "г"}, {"name": "моцарелла мини", "measurement_unit": "г"}, {"name": "моцарелла с травами", "measurement_unit": "г"}, {"name": "моцарелла шарик большой", "measurement_unit": "г"}, {"name": "мука", "measurement_unit": "г"}, {"name": "мука 1 сорт", "measurement_unit": "г"}, {"name": "мука 2 сорт", "measurement_unit": "г"}, {"name": "мука «Аладушкин»", "measurement_unit": "г"}, {"name": "мука грубого помола", "measurement_unit": "г"}, {"name": "мука для темпуры", "measurement_unit": "г"}, {"name": "мука из пророщенной пшеницы", "measurement_unit": "ст. л."}, {"name": "мука манитоба", "measurement_unit": "г"}, {"name": "мука самоподнимающаяся", "measurement_unit": "г"}, {"name": "мука с отрубями", "measurement_unit": "ч. л."}, {"name": "мука с семечками", "measurement_unit": "г"}, {"name": "мука хлебопекарная", "measurement_unit": "г"}, {"name": "мука цельнозерновая", "measurement_unit": "г"}, {"name": "мускат белый", "measurement_unit": "мл"}, {"name": "мускатное вино", "measurement_unit": "г"}, {"name": "мускатный орех", "measurement_unit": "г"}, {"name": "мускатный орех молотый", "measurement_unit": "г"}, {"name": "мюсли", "measurement_unit": "г"}, {"name": "мягкий творог", "measurement_unit": "г"}, {"name": "мясной бульон", "measurement_unit": "г"}, {"name": "мясной фарш", "measurement_unit": "г"}, {"name": "мясо", "measurement_unit": "г"}, {"name": "мясо дикого кабана", "measurement_unit": "г"}, {"name": "мясо криля", "measurement_unit": "г"}, {"name": "мясо на косточке", "measurement_unit": "кг"}, {"name": "мята", "measurement_unit": "г"}, {"name": "мята сушеная", "measurement_unit": "г"}, {"name": "мятный сироп", "measurement_unit": "г"}, {"name": "мятный шнапс", "measurement_unit": "г"}, {"name": "нардек", "measurement_unit": "г"}, {"name": "нектарины", "measurement_unit": "шт."}, {"name": "нога ягненка без кости", "measurement_unit": "г"}, {"name": "нори", "measurement_unit": "г"}, {"name": "нуга", "measurement_unit": "г"}, {"name": "нуга с орехами", "measurement_unit": "г"}, {"name": "нут", "measurement_unit": "г"}, {"name": "нутелла", "measurement_unit": "г"}, {"name": "нут консервированный", "measurement_unit": "г"}, {"name": "нутовая мука", "measurement_unit": "г"}, {"name": "облепиха", "measurement_unit": "г"}, {"name": "облепиха замороженная", "measurement_unit": "г"}, {"name": "облепиховый сироп", "measurement_unit": "стакан"}, {"name": "овощи", "measurement_unit": "г"}, {"name": "овощная смесь", "measurement_unit": "г"}, {"name": "овощная смесь замороженная", "measurement_unit": "г"}, {"name": "овощная смесь замороженная для wok", "measurement_unit": "г"}, {"name": "овощная смесь по-китайски", "measurement_unit": "г"}, {"name": "овощной бульон", "measurement_unit": "по вкусу"}, {"name": "овсяная мука", "measurement_unit": "г"}, {"name": "овсяное молоко", "measurement_unit": "стакан"}, {"name": "овсяное печенье", "measurement_unit": "г"}, {"name": "овсяное толокно", "measurement_unit": "г"}, {"name": "овсяные зерна", "measurement_unit": "г"}, {"name": "овсяные отруби", "measurement_unit": "г"}, {"name": "овсяные хлопья", "measurement_unit": "г"}, {"name": "овсяные хлопья быстрого приготовления", "measurement_unit": "г"}, {"name": "огуречный рассол", "measurement_unit": "стакан"}, {"name": "огурцы", "measurement_unit": "г"}, {"name": "огурцы консервированные", "measurement_unit": "шт."}, {"name": "огурцы малосольные", "measurement_unit": "шт."}, {"name": "огурцы маринованные", "measurement_unit": "банка"}, {"name": "огурцы свежие", "measurement_unit": "г"}, {"name": "огурцы соленые", "measurement_unit": "г"}, {"name": "одуванчики", "measurement_unit": "г"}, {"name": "окорок", "measurement_unit": "г"}, {"name": "окорок варено-копченый", "measurement_unit": "г"}, {"name": "окунь", "measurement_unit": "г"}, {"name": "окунь красный филе", "measurement_unit": "г"}, {"name": "окунь морской", "measurement_unit": "г"}, {"name": "окунь морской филе", "measurement_unit": "г"}, {"name": "окунь филе", "measurement_unit": "г"}, {"name": "оленина", "measurement_unit": "г"}, {"name": "оливки", "measurement_unit": "г"}, {"name": "оливки без косточек", "measurement_unit": "г"}, {"name": "оливки зеленые", "measurement_unit": "по вкусу"}, {"name": "оливки зеленые консервированные", "measurement_unit": "банка"}, {"name": "оливки каламата", "measurement_unit": "г"}, {"name": "оливки консервированные", "measurement_unit": "г"}, {"name": "оливки, фаршированные анчоусами", "measurement_unit": "г"}, {"name": "оливки черные", "measurement_unit": "по вкусу"}, {"name": "оливковая паста", "measurement_unit": "г"}, {"name": "оливковое масло", "measurement_unit": "г"}, {"name": "оливковое масло Extra Virgin", "measurement_unit": "г"}, {"name": "опунция плоды", "measurement_unit": "г"}, {"name": "опята", "measurement_unit": "по вкусу"}, {"name": "опята замороженные", "measurement_unit": "г"}, {"name": "опята маринованные", "measurement_unit": "г"}, {"name": "орегано", "measurement_unit": "г"}, {"name": "орегано свежий", "measurement_unit": "г"}, {"name": "орегано сушеный", "measurement_unit": "г"}, {"name": "орехи", "measurement_unit": "г"}, {"name": "орехи бразильские", "measurement_unit": "г"}, {"name": "орехи макадамия", "measurement_unit": "г"}, {"name": "орехи пекан", "measurement_unit": "г"}, {"name": "орехи пинии", "measurement_unit": "г"}, {"name": "ореховая крошка", "measurement_unit": "стакан"}, {"name": "ореховая паста", "measurement_unit": "шт."}, {"name": "ореховое масло", "measurement_unit": "ст. л."}, {"name": "ореховый ликер", "measurement_unit": "мл"}, {"name": "ореховый соус", "measurement_unit": "ст. л."}, {"name": "осетр", "measurement_unit": "г"}, {"name": "осетрина холодного копчения", "measurement_unit": "г"}, {"name": "осьминог", "measurement_unit": "г"}, {"name": "осьминоги консервированные", "measurement_unit": "г"}, {"name": "осьминоги мини", "measurement_unit": "г"}, {"name": "отруби", "measurement_unit": "г"}, {"name": "ошеек", "measurement_unit": "г"}, {"name": "пагр", "measurement_unit": "г"}, {"name": "пажитник", "measurement_unit": "г"}, {"name": "пажитник семена", "measurement_unit": "г"}, {"name": "палтус", "measurement_unit": "г"}, {"name": "пальмовое масло", "measurement_unit": "г"}, {"name": "пангасиус", "measurement_unit": "г"}, {"name": "панеттоне", "measurement_unit": "шт."}, {"name": "Панифарин", "measurement_unit": "г"}, {"name": "панчетта", "measurement_unit": "г"}, {"name": "папайя", "measurement_unit": "г"}, {"name": "папайя консервированная в собственном соку", "measurement_unit": "г"}, {"name": "папоротник", "measurement_unit": "г"}, {"name": "папоротник соленый", "measurement_unit": "упаковка"}, {"name": "паппарделле", "measurement_unit": "г"}, {"name": "паприка", "measurement_unit": "г"}, {"name": "паприка копченая", "measurement_unit": "ст. л."}, {"name": "паприка красная", "measurement_unit": "ст. л."}, {"name": "паприка красная молотая", "measurement_unit": "г"}, {"name": "паприка острая копченая", "measurement_unit": "г"}, {"name": "паприка сладкая", "measurement_unit": "г"}, {"name": "паприка сладкая копченая", "measurement_unit": "г"}, {"name": "паприка сладкая хлопьями", "measurement_unit": "ч. л."}, {"name": "пармезан", "measurement_unit": "г"}, {"name": "паста", "measurement_unit": "г"}, {"name": "паста веджимайт", "measurement_unit": "г"}, {"name": "паста тахини", "measurement_unit": "г"}, {"name": "паста хариса", "measurement_unit": "ст. л."}, {"name": "пастернак", "measurement_unit": "г"}, {"name": "пастила", "measurement_unit": "г"}, {"name": "пастила виноградная", "measurement_unit": "г"}, {"name": "патиссоны", "measurement_unit": "г"}, {"name": "патока", "measurement_unit": "г"}, {"name": "патока крахмальная", "measurement_unit": "г"}, {"name": "патока черная (меласса)", "measurement_unit": "г"}, {"name": "пахта", "measurement_unit": "г"}, {"name": "паштет", "measurement_unit": "г"}, {"name": "пекарский порошок", "measurement_unit": "г"}, {"name": "пекарский порошок", "measurement_unit": "ч. л."}, {"name": "пекорино", "measurement_unit": "г"}, {"name": "пектин", "measurement_unit": "г"}, {"name": "пеленгас", "measurement_unit": "г"}, {"name": "пельмени", "measurement_unit": "г"}, {"name": "пенне", "measurement_unit": "г"}, {"name": "пенне ригате", "measurement_unit": "г"}, {"name": "пеперончино", "measurement_unit": "ч. л."}, {"name": "пеперончино молотый", "measurement_unit": "щепотка"}, {"name": "переводной лист для шоколада", "measurement_unit": "шт."}, {"name": "перепелки", "measurement_unit": "тушка"}, {"name": "перец", "measurement_unit": "г"}, {"name": "перец белый", "measurement_unit": "г"}, {"name": "перец белый горошком", "measurement_unit": "по вкусу"}, {"name": "перец белый молотый", "measurement_unit": "г"}, {"name": "перец белый свежемолотый", "measurement_unit": "ч. л."}, {"name": "перец болгарский", "measurement_unit": "г"}, {"name": "перец болгарский желтый", "measurement_unit": "г"}, {"name": "перец болгарский зеленый", "measurement_unit": "г"}, {"name": "перец болгарский красный", "measurement_unit": "г"}, {"name": "перец горошком", "measurement_unit": "г"}, {"name": "перец горошком смесь", "measurement_unit": "г"}, {"name": "перец душистый", "measurement_unit": "щепотка"}, {"name": "перец душистый горошком", "measurement_unit": "г"}, {"name": "перец душистый молотый", "measurement_unit": "г"}, {"name": "перец испанский острый", "measurement_unit": "шт."}, {"name": "перец кайенский", "measurement_unit": "г"}, {"name": "перец кайенский красный", "measurement_unit": "г"}, {"name": "перец кайенский молотый", "measurement_unit": "щепотка"}, {"name": "перец красный", "measurement_unit": "г"}, {"name": "перец красный горошком", "measurement_unit": "г"}, {"name": "перец красный жгучий", "measurement_unit": "г"}, {"name": "перец красный молотый", "measurement_unit": "г"}, {"name": "перец красный острый", "measurement_unit": "г"}, {"name": "перец красный острый молотый", "measurement_unit": "по вкусу"}, {"name": "перец красный хлопьями", "measurement_unit": "щепотка"}, {"name": "перец лимонный", "measurement_unit": "г"}, {"name": "перец маринованный", "measurement_unit": "г"}, {"name": "перец острый", "measurement_unit": "г"}, {"name": "перец острый зеленый", "measurement_unit": "шт."}, {"name": "перец острый молотый", "measurement_unit": "щепотка"}, {"name": "перец падрон", "measurement_unit": "г"}, {"name": "перец пеперони", "measurement_unit": "г"}, {"name": "перец пеперони красный", "measurement_unit": "шт."}, {"name": "перец розовый горошком", "measurement_unit": "г"}, {"name": "перец свежемолотый смесь", "measurement_unit": "г"}, {"name": "перец сенегальский", "measurement_unit": "по вкусу"}, {"name": "перец сладкий", "measurement_unit": "г"}, {"name": "перец сладкий желтый", "measurement_unit": "г"}, {"name": "перец сладкий зеленый", "measurement_unit": "г"}, {"name": "перец сладкий красный", "measurement_unit": "г"}, {"name": "перец сладкий красный маринованный", "measurement_unit": "шт."}, {"name": "перец сладкий красный молотый", "measurement_unit": "г"}, {"name": "перец сладкий оранжевый", "measurement_unit": "г"}, {"name": "перец сладкий сушеный", "measurement_unit": "г"}, {"name": "перец сычуаньский", "measurement_unit": "г"}, {"name": "перец халапеньо", "measurement_unit": "г"}, {"name": "перец халапеньо маринованный", "measurement_unit": "шт."}, {"name": "перец черный", "measurement_unit": "ст. л."}, {"name": "перец черный горошком", "measurement_unit": "по вкусу"}, {"name": "перец черный молотый", "measurement_unit": "г"}, {"name": "перец черный свежемолотый", "measurement_unit": "г"}, {"name": "перец чили", "measurement_unit": "г"}, {"name": "перец чили зеленый", "measurement_unit": "стручок"}, {"name": "перец чили красный", "measurement_unit": "стручок"}, {"name": "перец чили маринованный", "measurement_unit": "по вкусу"}, {"name": "перец чили молотый", "measurement_unit": "г"}, {"name": "перец чили сухой", "measurement_unit": "ст. л."}, {"name": "перец чили хлопьями", "measurement_unit": "по вкусу"}, {"name": "перец ямайский", "measurement_unit": "г"}, {"name": "перловая крупа", "measurement_unit": "г"}, {"name": "перловая мука", "measurement_unit": "г"}, {"name": "персики", "measurement_unit": "г"}, {"name": "персики консервированные", "measurement_unit": "г"}, {"name": "персики сушеные", "measurement_unit": "горсть"}, {"name": "персиковое пюре", "measurement_unit": "г"}, {"name": "персиковый джем", "measurement_unit": "г"}, {"name": "персиковый мармелад", "measurement_unit": "ст. л."}, {"name": "персиковый сироп", "measurement_unit": "мл"}, {"name": "персиковый сок", "measurement_unit": "г"}, {"name": "перцовая паста", "measurement_unit": "ч. л."}, {"name": "петрушка", "measurement_unit": "г"}, {"name": "петрушка зелень", "measurement_unit": "г"}, {"name": "петрушка итальянская", "measurement_unit": "пучок"}, {"name": "петрушка корень", "measurement_unit": "г"}, {"name": "петрушка рубленая", "measurement_unit": "г"}, {"name": "петрушка сушеная", "measurement_unit": "г"}, {"name": "печень", "measurement_unit": "г"}, {"name": "печенье", "measurement_unit": "по вкусу"}, {"name": "печенье Oreo", "measurement_unit": "г"}, {"name": "печенье Амаретти", "measurement_unit": "г"}, {"name": "печенье бисквитное", "measurement_unit": "г"}, {"name": "печенье галетное", "measurement_unit": "шт."}, {"name": "печенье «Дамские пальчики»", "measurement_unit": "г"}, {"name": "печенье песочное", "measurement_unit": "г"}, {"name": "печенье рассыпчатое", "measurement_unit": "г"}, {"name": "печенье Савоярди", "measurement_unit": "г"}, {"name": "печенье сахарное", "measurement_unit": "г"}, {"name": "печенье сладкое", "measurement_unit": "г"}, {"name": "печенье сухое", "measurement_unit": "г"}, {"name": "печенье шоколадное", "measurement_unit": "г"}, {"name": "печенье Юбилейное молочное", "measurement_unit": "г"}, {"name": "пиво", "measurement_unit": "г"}, {"name": "пиво имбирное", "measurement_unit": "мл"}, {"name": "пиво нефильтрованное", "measurement_unit": "г"}, {"name": "пиво светлое", "measurement_unit": "г"}, {"name": "пиво темное", "measurement_unit": "банка"}, {"name": "пикша", "measurement_unit": "шт."}, {"name": "питы", "measurement_unit": "по вкусу"}, {"name": "повидло", "measurement_unit": "г"}, {"name": "подсолнечное масло", "measurement_unit": "г"}, {"name": "подсолнечные семечки", "measurement_unit": "г"}, {"name": "полба", "measurement_unit": "г"}, {"name": "полба недозрелая", "measurement_unit": "г"}, {"name": "полента", "measurement_unit": "по вкусу"}, {"name": "полента быстрого приготовления", "measurement_unit": "стакан"}, {"name": "помело", "measurement_unit": "г"}, {"name": "помидоры", "measurement_unit": "г"}, {"name": "помидоры бурые", "measurement_unit": "г"}, {"name": "помидоры вяленые", "measurement_unit": "по вкусу"}, {"name": "помидоры вяленые в масле", "measurement_unit": "г"}, {"name": "помидоры желтые", "measurement_unit": "шт."}, {"name": "помидоры зеленые", "measurement_unit": "кг"}, {"name": "помидоры консервированные", "measurement_unit": "г"}, {"name": "помидоры консервированные в собственном соку", "measurement_unit": "г"}, {"name": "помидоры консервированные в собственном соку с базиликом", "measurement_unit": "г"}, {"name": "помидоры протертые пассата", "measurement_unit": "г"}, {"name": "помидоры соленые", "measurement_unit": "шт."}, {"name": "помидоры сушеные хлопьями", "measurement_unit": "г"}, {"name": "помидоры черри", "measurement_unit": "г"}, {"name": "помидоры черри желтые", "measurement_unit": "г"}, {"name": "попкорн", "measurement_unit": "г"}, {"name": "поросенок", "measurement_unit": "кг"}, {"name": "портвейн", "measurement_unit": "г"}, {"name": "портобелло", "measurement_unit": "г"}, {"name": "портулак", "measurement_unit": "г"}, {"name": "посыпка кондитерская", "measurement_unit": "по вкусу"}, {"name": "почки", "measurement_unit": "г"}, {"name": "приправа 4 перца", "measurement_unit": "г"}, {"name": "приправа 5 специй (five spice)", "measurement_unit": "ч. л."}, {"name": "приправа для баранины", "measurement_unit": "ст. л."}, {"name": "приправа для картофеля", "measurement_unit": "г"}, {"name": "приправа для курицы", "measurement_unit": "г"}, {"name": "приправа для макарон", "measurement_unit": "по вкусу"}, {"name": "приправа для маринования свинины", "measurement_unit": "по вкусу"}, {"name": "приправа для морепродуктов", "measurement_unit": "по вкусу"}, {"name": "приправа для мяса", "measurement_unit": "г"}, {"name": "приправа для паэльи", "measurement_unit": "по вкусу"}, {"name": "приправа для пиццы", "measurement_unit": "ч. л."}, {"name": "приправа для плова", "measurement_unit": "г"}, {"name": "приправа для птицы", "measurement_unit": "ст. л."}, {"name": "приправа для рыбы", "measurement_unit": "г"}, {"name": "приправа для салатов", "measurement_unit": "по вкусу"}, {"name": "приправа заатар", "measurement_unit": "ч. л."}, {"name": "приправа креольская", "measurement_unit": "ст. л."}, {"name": "приправа с сушеными грибами", "measurement_unit": "ч. л."}, {"name": "приправы", "measurement_unit": "г"}, {"name": "прованские травы", "measurement_unit": "г"}, {"name": "проволоне", "measurement_unit": "г"}, {"name": "просекко", "measurement_unit": "мл"}, {"name": "простокваша", "measurement_unit": "г"}, {"name": "протеин сывороточный", "measurement_unit": "г"}, {"name": "прошутто", "measurement_unit": "г"}, {"name": "пряники", "measurement_unit": "г"}, {"name": "пряничные специи", "measurement_unit": "г"}, {"name": "пряности", "measurement_unit": "г"}, {"name": "псиллиум", "measurement_unit": "г"}, {"name": "птитим", "measurement_unit": "г"}, {"name": "пудинг", "measurement_unit": "г"}, {"name": "пудинг ванильный", "measurement_unit": "г"}, {"name": "пудинг ванильный инстант", "measurement_unit": "упаковка"}, {"name": "пудинг карамельный", "measurement_unit": "г"}, {"name": "пшеница", "measurement_unit": "г"}, {"name": "пшеничная крупа", "measurement_unit": "г"}, {"name": "пшеничная мука", "measurement_unit": "г"}, {"name": "пшеничная мука цельнозерновая", "measurement_unit": "г"}, {"name": "пшеничные зародыши", "measurement_unit": "стакан"}, {"name": "пшеничные отруби", "measurement_unit": "г"}, {"name": "пшеничные ростки", "measurement_unit": "г"}, {"name": "пшеничные хлопья", "measurement_unit": "г"}, {"name": "пшенные хлопья", "measurement_unit": "ст. л."}, {"name": "пшено", "measurement_unit": "г"}, {"name": "пыльца цветочная", "measurement_unit": "г"}, {"name": "пюре", "measurement_unit": "по вкусу"}, {"name": "радиккио", "measurement_unit": "шт."}, {"name": "разрыхлитель", "measurement_unit": "г"}, {"name": "раки", "measurement_unit": "шт."}, {"name": "раковые шейки", "measurement_unit": "г"}, {"name": "раковые шейки в рассоле", "measurement_unit": "г"}, {"name": "рамбутан", "measurement_unit": "г"}, {"name": "рапаны", "measurement_unit": "г"}, {"name": "рапсовое масло", "measurement_unit": "по вкусу"}, {"name": "рассол", "measurement_unit": "г"}, {"name": "рассол от каперсов", "measurement_unit": "ст. л."}, {"name": "рассол от оливок", "measurement_unit": "ст. л."}, {"name": "растительное масло", "measurement_unit": "г"}, {"name": "растительное масло для жарки", "measurement_unit": "г"}, {"name": "растительное масло нерафинированное", "measurement_unit": "стакан"}, {"name": "растительное масло рафинированное", "measurement_unit": "г"}, {"name": "растительное молоко", "measurement_unit": "стакан"}, {"name": "ревень", "measurement_unit": "г"}, {"name": "реган", "measurement_unit": "веточка"}, {"name": "редис", "measurement_unit": "г"}, {"name": "редька", "measurement_unit": "г"}, {"name": "редька белая", "measurement_unit": "шт."}, {"name": "редька зеленая", "measurement_unit": "шт."}, {"name": "редька черная", "measurement_unit": "шт."}, {"name": "репа", "measurement_unit": "г"}, {"name": "репа белая", "measurement_unit": "шт."}, {"name": "ржаная закваска", "measurement_unit": "г"}, {"name": "ржаная закваска густая", "measurement_unit": "г"}, {"name": "ржаная мука", "measurement_unit": "г"}, {"name": "ржаные отруби", "measurement_unit": "г"}, {"name": "ригатони", "measurement_unit": "г"}, {"name": "рикотта", "measurement_unit": "г"}, {"name": "рикотта твердая", "measurement_unit": "г"}, {"name": "рис", "measurement_unit": "г"}, {"name": "рис арборио", "measurement_unit": "г"}, {"name": "рис басмати", "measurement_unit": "г"}, {"name": "рис бурый", "measurement_unit": "г"}, {"name": "рис бурый и дикий смесь", "measurement_unit": "г"}, {"name": "рис вареный", "measurement_unit": "г"}, {"name": "рис виола", "measurement_unit": "г"}, {"name": "рис девзира", "measurement_unit": "г"}, {"name": "рис дикий", "measurement_unit": "г"}, {"name": "рис дикий и золотистый смесь", "measurement_unit": "г"}, {"name": "рис длиннозерный", "measurement_unit": "г"}, {"name": "рис длиннозерный золотистый", "measurement_unit": "г"}, {"name": "рис для плова", "measurement_unit": "г"}, {"name": "рис для пудинга", "measurement_unit": "г"}, {"name": "рис для ризотто", "measurement_unit": "г"}, {"name": "рис для суши", "measurement_unit": "г"}, {"name": "рис жасминовый", "measurement_unit": "г"}, {"name": "рис золотистый", "measurement_unit": "г"}, {"name": "рис индика", "measurement_unit": "г"}, {"name": "рис италика", "measurement_unit": "г"}, {"name": "рис карнароли", "measurement_unit": "г"}, {"name": "рис красный", "measurement_unit": "г"}, {"name": "рис круглозерный", "measurement_unit": "г"}, {"name": "рис кубанский", "measurement_unit": "г"}, {"name": "рисовая бумага", "measurement_unit": "г"}, {"name": "рисовая лапша", "measurement_unit": "г"}, {"name": "рисовая мука", "measurement_unit": "г"}, {"name": "рисовое вино", "measurement_unit": "ч. л."}, {"name": "рисовые хлопья", "measurement_unit": "г"}, {"name": "рисовые шарики воздушные", "measurement_unit": "г"}, {"name": "рисовый крахмал", "measurement_unit": "ст. л."}, {"name": "рисовый уксус", "measurement_unit": "по вкусу"}, {"name": "рис пропаренный", "measurement_unit": "г"}, {"name": "рис пропаренный и дикий смесь", "measurement_unit": "г"}, {"name": "рис японика", "measurement_unit": "г"}, {"name": "рожь", "measurement_unit": "г"}, {"name": "розмарин", "measurement_unit": "шт."}, {"name": "розмарин сушеный", "measurement_unit": "по вкусу"}, {"name": "розовая вода", "measurement_unit": "г"}, {"name": "розовые бутоны сушеные", "measurement_unit": "г"}, {"name": "розовые лепестки", "measurement_unit": "г"}, {"name": "розы", "measurement_unit": "г"}, {"name": "рокфор", "measurement_unit": "г"}, {"name": "ром", "measurement_unit": "бутылка"}, {"name": "ромашка сушеная", "measurement_unit": "г"}, {"name": "ромовый экстракт", "measurement_unit": "ч. л."}, {"name": "ром темный", "measurement_unit": "г"}, {"name": "ростбиф", "measurement_unit": "г"}, {"name": "рукола", "measurement_unit": "г"}, {"name": "рулька", "measurement_unit": "по вкусу"}, {"name": "рыба", "measurement_unit": "г"}, {"name": "рыба белая", "measurement_unit": "г"}, {"name": "рыба белая филе", "measurement_unit": "г"}, {"name": "рыба консервированная", "measurement_unit": "банка"}, {"name": "рыба копченая", "measurement_unit": "г"}, {"name": "рыба копченая филе", "measurement_unit": "г"}, {"name": "рыба красная", "measurement_unit": "г"}, {"name": "рыба красная соленая", "measurement_unit": "г"}, {"name": "рыба красная филе", "measurement_unit": "г"}, {"name": "рыба-меч", "measurement_unit": "г"}, {"name": "рыба морская", "measurement_unit": "г"}, {"name": "рыба солнечник филе", "measurement_unit": "шт."}, {"name": "рыба-соль", "measurement_unit": "тушка"}, {"name": "рыбное филе", "measurement_unit": "г"}, {"name": "рыбные консервы", "measurement_unit": "г"}, {"name": "рыбные кости", "measurement_unit": "г"}, {"name": "рыбные обрезки, головы, плавники", "measurement_unit": "по вкусу"}, {"name": "рыбный бульон", "measurement_unit": "г"}, {"name": "рыбный соус", "measurement_unit": "г"}, {"name": "рыбный соус Nam Pla", "measurement_unit": "г"}, {"name": "рыбный соус тайский", "measurement_unit": "г"}, {"name": "рыбный фарш", "measurement_unit": "г"}, {"name": "рябина черноплодная", "measurement_unit": "г"}, {"name": "рябчик", "measurement_unit": "г"}, {"name": "ряженка", "measurement_unit": "г"}, {"name": "ряженка 4%", "measurement_unit": "г"}, {"name": "сайда", "measurement_unit": "г"}, {"name": "сайда филе", "measurement_unit": "г"}, {"name": "сайра", "measurement_unit": "г"}, {"name": "сайра консервированная", "measurement_unit": "банка"}, {"name": "саке", "measurement_unit": "ст. л."}, {"name": "салака", "measurement_unit": "г"}, {"name": "салат", "measurement_unit": "г"}, {"name": "салат айсберг", "measurement_unit": "г"}, {"name": "салат китайский", "measurement_unit": "г"}, {"name": "салат корн", "measurement_unit": "пучок"}, {"name": "салат кочанный", "measurement_unit": "г"}, {"name": "салат кучерявый", "measurement_unit": "г"}, {"name": "салат листовой", "measurement_unit": "г"}, {"name": "салатный микс", "measurement_unit": "г"}, {"name": "салат романо", "measurement_unit": "г"}, {"name": "салат фриссе", "measurement_unit": "г"}, {"name": "сало", "measurement_unit": "г"}, {"name": "сало копченое в перце", "measurement_unit": "г"}, {"name": "сало копченое с мясными прослойками", "measurement_unit": "г"}, {"name": "сало с мясными прослойками", "measurement_unit": "г"}, {"name": "сальник", "measurement_unit": "г"}, {"name": "сальса", "measurement_unit": "г"}, {"name": "сальса верде", "measurement_unit": "ч. л."}, {"name": "салями", "measurement_unit": "г"}, {"name": "салями итальянская", "measurement_unit": "г"}, {"name": "сардельки", "measurement_unit": "г"}, {"name": "сардельки копченые", "measurement_unit": "г"}, {"name": "сардинки маленькие", "measurement_unit": "шт."}, {"name": "сардины", "measurement_unit": "г"}, {"name": "сардины в масле", "measurement_unit": "банка"}, {"name": "сахар", "measurement_unit": "г"}, {"name": "сахар ванильный", "measurement_unit": "г"}, {"name": "сахар демерара", "measurement_unit": "г"}, {"name": "сахар жемчужный", "measurement_unit": "г"}, {"name": "сахар коричневый", "measurement_unit": "г"}, {"name": "сахар коричневый крупнокристаллический", "measurement_unit": "г"}, {"name": "сахар мусковадо", "measurement_unit": "горсть"}, {"name": "сахарная пудра", "measurement_unit": "г"}, {"name": "сахарная пудра апельсиновая", "measurement_unit": "г"}, {"name": "сахарная пудра ванильная", "measurement_unit": "г"}, {"name": "сахарные жемчужинки", "measurement_unit": "г"}, {"name": "сахарные кондитерские украшения", "measurement_unit": "горсть"}, {"name": "сахарный песок", "measurement_unit": "г"}, {"name": "сахарный песок крупный", "measurement_unit": "г"}, {"name": "сахарный песок мелкий", "measurement_unit": "г"}, {"name": "сахарный сироп", "measurement_unit": "г"}, {"name": "сахар пальмовый", "measurement_unit": "г"}, {"name": "сахар-рафинад", "measurement_unit": "г"}, {"name": "сахар-рафинад с корицей", "measurement_unit": "г"}, {"name": "сахар тростниковый", "measurement_unit": "г"}, {"name": "сванская соль", "measurement_unit": "г"}, {"name": "свекла", "measurement_unit": "г"}, {"name": "свекла вареная", "measurement_unit": "г"}, {"name": "свекольная ботва", "measurement_unit": "г"}, {"name": "свекольные листья", "measurement_unit": "г"}, {"name": "свиная вырезка", "measurement_unit": "г"}, {"name": "свиная голова", "measurement_unit": "г"}, {"name": "свиная грудинка", "measurement_unit": "г"}, {"name": "свиная корейка", "measurement_unit": "г"}, {"name": "свиная корейка копченая", "measurement_unit": "г"}, {"name": "свиная корейка на кости", "measurement_unit": "г"}, {"name": "свиная лопатка варено-копченая", "measurement_unit": "г"}, {"name": "свиная мякоть", "measurement_unit": "г"}, {"name": "свиная пашина", "measurement_unit": "кг"}, {"name": "свиная печень", "measurement_unit": "г"}, {"name": "свиная рулька", "measurement_unit": "по вкусу"}, {"name": "свиная рулька варено-копченая", "measurement_unit": "г"}, {"name": "свиная рулька копченая", "measurement_unit": "г"}, {"name": "свиная шейка", "measurement_unit": "кусок"}, {"name": "свинина", "measurement_unit": "г"}, {"name": "свинина вареная", "measurement_unit": "г"}, {"name": "свинина нежирная", "measurement_unit": "г"}, {"name": "свинина с жирком", "measurement_unit": "г"}, {"name": "свиное сердце", "measurement_unit": "г"}, {"name": "свиное филе", "measurement_unit": "г"}, {"name": "свиной подчеревок", "measurement_unit": "г"}, {"name": "свиной фарш", "measurement_unit": "г"}, {"name": "свиной язык", "measurement_unit": "г"}, {"name": "свиные котлеты на косточке", "measurement_unit": "шт."}, {"name": "свиные легкие", "measurement_unit": "г"}, {"name": "свиные ножки", "measurement_unit": "г"}, {"name": "свиные отбивные", "measurement_unit": "г"}, {"name": "свиные отбивные на косточке", "measurement_unit": "г"}, {"name": "свиные ребра", "measurement_unit": "г"}, {"name": "свиные уши", "measurement_unit": "шт."}, {"name": "свиные щечки", "measurement_unit": "шт."}, {"name": "свити", "measurement_unit": "г"}, {"name": "сельдерей", "measurement_unit": "г"}, {"name": "сельдерей зелень", "measurement_unit": "г"}, {"name": "сельдерей корень", "measurement_unit": "г"}, {"name": "сельдерей корень сушеный", "measurement_unit": "по вкусу"}, {"name": "сельдерейная соль", "measurement_unit": "г"}, {"name": "сельдерей семена", "measurement_unit": "ч. л."}, {"name": "сельдерей стебли", "measurement_unit": "г"}, {"name": "сельдь", "measurement_unit": "г"}, {"name": "сельдь слабосоленая", "measurement_unit": "г"}, {"name": "сельдь соленая", "measurement_unit": "шт."}, {"name": "сельдь филе", "measurement_unit": "г"}, {"name": "семга", "measurement_unit": "г"}, {"name": "семга копченая", "measurement_unit": "г"}, {"name": "семга свежая", "measurement_unit": "г"}, {"name": "семга соленая", "measurement_unit": "г"}, {"name": "семга филе на коже", "measurement_unit": "г"}, {"name": "семечки", "measurement_unit": "г"}, {"name": "семечки смесь", "measurement_unit": "ст. л."}, {"name": "семолина", "measurement_unit": "г"}, {"name": "сервелат варено-копченый", "measurement_unit": "г"}, {"name": "сибас", "measurement_unit": "г"}, {"name": "сидр", "measurement_unit": "г"}, {"name": "сироп", "measurement_unit": "г"}, {"name": "сироп от консервированных груш", "measurement_unit": "г"}, {"name": "сироп от консервированных персиков", "measurement_unit": "ст. л."}, {"name": "сироп топинамбура", "measurement_unit": "стакан"}, {"name": "скумбрия", "measurement_unit": "по вкусу"}, {"name": "скумбрия свежая", "measurement_unit": "г"}, {"name": "скумбрия филе", "measurement_unit": "г"}, {"name": "скумбрия холодного копчения", "measurement_unit": "г"}, {"name": "сливки", "measurement_unit": "упаковка"}, {"name": "сливки 10-20%", "measurement_unit": "г"}, {"name": "сливки 15%", "measurement_unit": "г"}, {"name": "сливки 20%", "measurement_unit": "г"}, {"name": "сливки 33-35%", "measurement_unit": "г"}, {"name": "сливки жирные", "measurement_unit": "г"}, {"name": "сливки кондитерские", "measurement_unit": "г"}, {"name": "сливовая паста", "measurement_unit": "г"}, {"name": "сливовое варенье", "measurement_unit": "г"}, {"name": "сливовое вино", "measurement_unit": "г"}, {"name": "сливовый джем", "measurement_unit": "г"}, {"name": "сливовый ликер", "measurement_unit": "ст. л."}, {"name": "сливовый соус", "measurement_unit": "г"}, {"name": "сливочное масло", "measurement_unit": "г"}, {"name": "сливы", "measurement_unit": "кг"}, {"name": "сливы замороженные", "measurement_unit": "г"}, {"name": "смалец", "measurement_unit": "г"}, {"name": "смесь для кекса", "measurement_unit": "шт."}, {"name": "смесь для оладий", "measurement_unit": "г"}, {"name": "смесь для хлеба 8 злаков", "measurement_unit": "г"}, {"name": "сметана", "measurement_unit": "г"}, {"name": "сметана 10%", "measurement_unit": "г"}, {"name": "сметана 15%", "measurement_unit": "ч. л."}, {"name": "сметана 18%", "measurement_unit": "г"}, {"name": "сметана 20%", "measurement_unit": "г"}, {"name": "сметана 25%", "measurement_unit": "г"}, {"name": "сметана 30%", "measurement_unit": "г"}, {"name": "сметана 35%", "measurement_unit": "г"}, {"name": "сметана жирная", "measurement_unit": "г"}, {"name": "сметана нежирная", "measurement_unit": "г"}, {"name": "сметана некислая", "measurement_unit": "г"}, {"name": "смородина сушеная", "measurement_unit": "г"}, {"name": "смородиновые листья", "measurement_unit": "г"}, {"name": "сморчки сухие", "measurement_unit": "г"}, {"name": "снежок", "measurement_unit": "л"}, {"name": "сныть", "measurement_unit": "г"}, {"name": "сода", "measurement_unit": "г"}, {"name": "соевая мука", "measurement_unit": "г"}, {"name": "соевое масло", "measurement_unit": "г"}, {"name": "соевое молоко", "measurement_unit": "г"}, {"name": "соевые ростки", "measurement_unit": "г"}, {"name": "соевый соус", "measurement_unit": "г"}, {"name": "сок", "measurement_unit": "г"}, {"name": "сок из красных апельсинов", "measurement_unit": "мл"}, {"name": "сок мультивитаминный", "measurement_unit": "мл"}, {"name": "сок юзу", "measurement_unit": "мл"}, {"name": "солод", "measurement_unit": "ч. л."}, {"name": "солод жидкий", "measurement_unit": "г"}, {"name": "солодовый экстракт", "measurement_unit": "г"}, {"name": "солод темный", "measurement_unit": "г"}, {"name": "соломка", "measurement_unit": "г"}, {"name": "соль", "measurement_unit": "г"}, {"name": "соль гималайская", "measurement_unit": "г"}, {"name": "соль крупного помола", "measurement_unit": "г"}, {"name": "соль морская", "measurement_unit": "г"}, {"name": "сом филе", "measurement_unit": "г"}, {"name": "сосиски", "measurement_unit": "г"}, {"name": "сосиски из куриного фарша", "measurement_unit": "шт."}, {"name": "сосиски копченые", "measurement_unit": "г"}, {"name": "соус", "measurement_unit": "г"}, {"name": "соус black bean", "measurement_unit": "ст. л."}, {"name": "соус sambal oelek", "measurement_unit": "ч. л."}, {"name": "соус барбекю", "measurement_unit": "г"}, {"name": "соус краснодарский", "measurement_unit": "г"}, {"name": "соус красный острый", "measurement_unit": "г"}, {"name": "соус мирин", "measurement_unit": "по вкусу"}, {"name": "соус наршараб", "measurement_unit": "г"}, {"name": "соус острый", "measurement_unit": "г"}, {"name": "соус песто", "measurement_unit": "по вкусу"}, {"name": "соус сацебели", "measurement_unit": "г"}, {"name": "соус табаско", "measurement_unit": "капля"}, {"name": "соус терияки", "measurement_unit": "г"}, {"name": "соус ткемали", "measurement_unit": "стакан"}, {"name": "соус ткемали благородный", "measurement_unit": "г"}, {"name": "соус ткемали ранний", "measurement_unit": "ст. л."}, {"name": "соус устричный", "measurement_unit": "ч. л."}, {"name": "соус чили", "measurement_unit": "г"}, {"name": "соус чили сладкий", "measurement_unit": "ч. л."}, {"name": "соус экзотический", "measurement_unit": "г"}, {"name": "соя", "measurement_unit": "г"}, {"name": "спагетти", "measurement_unit": "г"}, {"name": "спагетти № 3", "measurement_unit": "г"}, {"name": "спагетти № 5", "measurement_unit": "г"}, {"name": "спагетти лунги", "measurement_unit": "г"}, {"name": "спаржа", "measurement_unit": "кг"}, {"name": "спаржа белая", "measurement_unit": "г"}, {"name": "спаржа зеленая", "measurement_unit": "г"}, {"name": "спаржа молодая", "measurement_unit": "г"}, {"name": "спек", "measurement_unit": "г"}, {"name": "спельта", "measurement_unit": "стакан"}, {"name": "спельтовая (полбяная) мука", "measurement_unit": "г"}, {"name": "специи", "measurement_unit": "г"}, {"name": "спирт", "measurement_unit": "г"}, {"name": "спирулина порошок", "measurement_unit": "г"}, {"name": "спред", "measurement_unit": "г"}, {"name": "ставрида", "measurement_unit": "г"}, {"name": "стейк семги", "measurement_unit": "шт."}, {"name": "стейк семги", "measurement_unit": "г"}, {"name": "стеклянная лапша", "measurement_unit": "г"}, {"name": "страчателла", "measurement_unit": "г"}, {"name": "судак", "measurement_unit": "г"}, {"name": "судак филе", "measurement_unit": "г"}, {"name": "судак филе на коже", "measurement_unit": "г"}, {"name": "сулугуни", "measurement_unit": "г"}, {"name": "сулугуни копченый", "measurement_unit": "г"}, {"name": "сумах", "measurement_unit": "г"}, {"name": "суповой набор", "measurement_unit": "г"}, {"name": "сухари", "measurement_unit": "по вкусу"}, {"name": "сухари белые", "measurement_unit": "г"}, {"name": "сухари молотые", "measurement_unit": "г"}, {"name": "сухари панировочные", "measurement_unit": "г"}, {"name": "сухари ржаные", "measurement_unit": "г"}, {"name": "сухарная крошка", "measurement_unit": "г"}, {"name": "сухофрукты", "measurement_unit": "г"}, {"name": "сухофрукты тропические", "measurement_unit": "по вкусу"}, {"name": "сушки", "measurement_unit": "г"}, {"name": "сыворотка", "measurement_unit": "г"}, {"name": "сыр", "measurement_unit": "г"}, {"name": "сыр tete de moine", "measurement_unit": "г"}, {"name": "сыр Австрия блю", "measurement_unit": "г"}, {"name": "сыр адыгейский", "measurement_unit": "г"}, {"name": "сыр бри", "measurement_unit": "г"}, {"name": "сыр буко", "measurement_unit": "г"}, {"name": "сыр гауда", "measurement_unit": "г"}, {"name": "сыр гойя", "measurement_unit": "г"}, {"name": "сыр голландский", "measurement_unit": "г"}, {"name": "сыр голубой", "measurement_unit": "г"}, {"name": "сыр гравьера", "measurement_unit": "г"}, {"name": "сыр джугас", "measurement_unit": "г"}, {"name": "сыр домашний", "measurement_unit": "г"}, {"name": "сыр дорблю", "measurement_unit": "г"}, {"name": "сыр имеретинский", "measurement_unit": "г"}, {"name": "сыр кефалотири", "measurement_unit": "г"}, {"name": "сырки творожные", "measurement_unit": "г"}, {"name": "сыр козий мягкий", "measurement_unit": "г"}, {"name": "сыр козий твердый", "measurement_unit": "г"}, {"name": "сыр колбасный", "measurement_unit": "г"}, {"name": "сыр копченый", "measurement_unit": "г"}, {"name": "сыр коттедж", "measurement_unit": "г"}, {"name": "сыр Маскарпоне", "measurement_unit": "г"}, {"name": "сыр мраморный", "measurement_unit": "г"}, {"name": "сыр мягкий", "measurement_unit": "по вкусу"}, {"name": "сыр овечий", "measurement_unit": "г"}, {"name": "сыр панир", "measurement_unit": "г"}, {"name": "сыр пеше миньон", "measurement_unit": "г"}, {"name": "сыр плавленый", "measurement_unit": "г"}, {"name": "сыр плавленый шоколадный", "measurement_unit": "г"}, {"name": "сыр пластинками", "measurement_unit": "г"}, {"name": "сыр полутвердый", "measurement_unit": "г"}, {"name": "сыр провола", "measurement_unit": "г"}, {"name": "сыр российский", "measurement_unit": "г"}, {"name": "сыр скаморца", "measurement_unit": "г"}, {"name": "сыр скаморца копченый", "measurement_unit": "г"}, {"name": "сыр сливочный", "measurement_unit": "г"}, {"name": "сыр с плесенью", "measurement_unit": "г"}, {"name": "сыр с плесенью мягкий", "measurement_unit": "г"}, {"name": "сыр твердый", "measurement_unit": "г"}, {"name": "сыр филадельфия", "measurement_unit": "г"}, {"name": "сыр фонтина", "measurement_unit": "г"}, {"name": "сыр хаварти", "measurement_unit": "г"}, {"name": "сыр швейцарский", "measurement_unit": "г"}, {"name": "сычужный фермент", "measurement_unit": "ч. л."}, {"name": "таледжо", "measurement_unit": "г"}, {"name": "тальолини", "measurement_unit": "г"}, {"name": "тальятелле", "measurement_unit": "г"}, {"name": "тальятелле-гнезда", "measurement_unit": "шт."}, {"name": "тамаринд", "measurement_unit": "шт."}, {"name": "тамариндовая паста", "measurement_unit": "ч. л."}, {"name": "тапиока", "measurement_unit": "г"}, {"name": "тарталетки", "measurement_unit": "по вкусу"}, {"name": "тартар", "measurement_unit": "ст. л."}, {"name": "тархун", "measurement_unit": "г"}, {"name": "творог", "measurement_unit": "г"}, {"name": "творог 18%", "measurement_unit": "г"}, {"name": "творог 2%", "measurement_unit": "г"}, {"name": "творог 5%", "measurement_unit": "г"}, {"name": "творог 9%", "measurement_unit": "г"}, {"name": "творог жирный", "measurement_unit": "г"}, {"name": "творог зерненый", "measurement_unit": "г"}, {"name": "творог обезжиренный", "measurement_unit": "г"}, {"name": "творожная масса", "measurement_unit": "г"}, {"name": "творожная паста", "measurement_unit": "г"}, {"name": "творожный сыр", "measurement_unit": "г"}, {"name": "творожный сыр соленый", "measurement_unit": "г"}, {"name": "творожок клубничный", "measurement_unit": "г"}, {"name": "текила", "measurement_unit": "стакан"}, {"name": "телятина", "measurement_unit": "по вкусу"}, {"name": "телятина вареная", "measurement_unit": "г"}, {"name": "телячий фарш", "measurement_unit": "г"}, {"name": "телячьи отбивные на косточке", "measurement_unit": "шт."}, {"name": "телячьи шницели", "measurement_unit": "шт."}, {"name": "телячьи эскалопы", "measurement_unit": "г"}, {"name": "телячья вырезка", "measurement_unit": "г"}, {"name": "телячья печень", "measurement_unit": "г"}, {"name": "телячья щека", "measurement_unit": "шт."}, {"name": "тесто бездрожжевое", "measurement_unit": "г"}, {"name": "тесто готовое", "measurement_unit": "г"}, {"name": "тесто для вонтонов", "measurement_unit": "г"}, {"name": "тесто для пиццы", "measurement_unit": "шт."}, {"name": "тесто дрожжевое", "measurement_unit": "по вкусу"}, {"name": "тесто катаифи", "measurement_unit": "г"}, {"name": "тесто макаронное", "measurement_unit": "г"}, {"name": "тесто макаронное для лазаньи", "measurement_unit": "г"}, {"name": "тесто пельменное", "measurement_unit": "г"}, {"name": "тесто песочное", "measurement_unit": "по вкусу"}, {"name": "тесто пресное", "measurement_unit": "г"}, {"name": "тесто пряничное", "measurement_unit": "г"}, {"name": "тесто слоеное", "measurement_unit": "г"}, {"name": "тесто слоеное бездрожжевое", "measurement_unit": "по вкусу"}, {"name": "тесто слоеное дрожжевое", "measurement_unit": "кг"}, {"name": "тесто фило", "measurement_unit": "г"}, {"name": "тилапия", "measurement_unit": "г"}, {"name": "тилапия филе", "measurement_unit": "г"}, {"name": "тильзитер", "measurement_unit": "г"}, {"name": "тимьян", "measurement_unit": "горсть"}, {"name": "тимьян лимонный", "measurement_unit": "веточка"}, {"name": "тимьян свежий", "measurement_unit": "по вкусу"}, {"name": "тимьян сушеный", "measurement_unit": "г"}, {"name": "ткемали", "measurement_unit": "г"}, {"name": "тмин", "measurement_unit": "г"}, {"name": "тмин молотый", "measurement_unit": "г"}, {"name": "томатная паста", "measurement_unit": "г"}, {"name": "томатное пюре", "measurement_unit": "г"}, {"name": "томатный концентрат", "measurement_unit": "г"}, {"name": "томатный порошок", "measurement_unit": "г"}, {"name": "томатный сок", "measurement_unit": "г"}, {"name": "томатный соус", "measurement_unit": "г"}, {"name": "томатный соус итальянский", "measurement_unit": "г"}, {"name": "томатный соус острый", "measurement_unit": "г"}, {"name": "томатный соус с базиликом", "measurement_unit": "г"}, {"name": "тоник", "measurement_unit": "бутылка"}, {"name": "топинамбур", "measurement_unit": "г"}, {"name": "топленое масло", "measurement_unit": "г"}, {"name": "тортильи", "measurement_unit": "по вкусу"}, {"name": "тортильони", "measurement_unit": "г"}, {"name": "тофу", "measurement_unit": "г"}, {"name": "травы ароматные", "measurement_unit": "г"}, {"name": "травы пряные с перцем", "measurement_unit": "ч. л."}, {"name": "травы сухие", "measurement_unit": "г"}, {"name": "треска", "measurement_unit": "г"}, {"name": "треска печень", "measurement_unit": "г"}, {"name": "треска филе", "measurement_unit": "г"}, {"name": "трюфель", "measurement_unit": "г"}, {"name": "трюфельная крошка", "measurement_unit": "г"}, {"name": "трюфельное масло", "measurement_unit": "ст. л."}, {"name": "трюфель черный", "measurement_unit": "шт."}, {"name": "тунец", "measurement_unit": "по вкусу"}, {"name": "тунец консервированный", "measurement_unit": "г"}, {"name": "тунец филе", "measurement_unit": "г"}, {"name": "тушенка", "measurement_unit": "г"}, {"name": "тыква", "measurement_unit": "г"}, {"name": "тыквенное масло", "measurement_unit": "шт."}, {"name": "тыквенное пюре", "measurement_unit": "г"}, {"name": "тыквенные семечки", "measurement_unit": "г"}, {"name": "тюлька свежая", "measurement_unit": "г"}, {"name": "угорь", "measurement_unit": "г"}, {"name": "угорь копченый", "measurement_unit": "г"}, {"name": "угурт", "measurement_unit": "г"}, {"name": "укроп", "measurement_unit": "г"}, {"name": "укропное семя", "measurement_unit": "ч. л."}, {"name": "укроп свежий", "measurement_unit": "г"}, {"name": "укроп сушеный", "measurement_unit": "г"}, {"name": "уксус", "measurement_unit": "г"}, {"name": "уксус 9%", "measurement_unit": "г"}, {"name": "уксус из сидра", "measurement_unit": "ст. л."}, {"name": "уксусная эссенция", "measurement_unit": "г"}, {"name": "уксус столовый", "measurement_unit": "г"}, {"name": "улитки", "measurement_unit": "г"}, {"name": "улитки виноградные", "measurement_unit": "шт."}, {"name": "урюк", "measurement_unit": "г"}, {"name": "устрицы", "measurement_unit": "г"}, {"name": "утиная грудка", "measurement_unit": "г"}, {"name": "утиная печень", "measurement_unit": "г"}, {"name": "утиное филе", "measurement_unit": "г"}, {"name": "утиные бедрышки", "measurement_unit": "г"}, {"name": "утиные ножки", "measurement_unit": "по вкусу"}, {"name": "утка", "measurement_unit": "по вкусу"}, {"name": "утка печеная", "measurement_unit": "г"}, {"name": "утка тушка", "measurement_unit": "тушка"}, {"name": "уцхо-сунели", "measurement_unit": "г"}, {"name": "фазан", "measurement_unit": "г"}, {"name": "фарш (баранина и говядина)", "measurement_unit": "г"}, {"name": "фарш (свинина и курица)", "measurement_unit": "г"}, {"name": "фасоль", "measurement_unit": "г"}, {"name": "фасоль белая", "measurement_unit": "г"}, {"name": "фасоль белая консервированная", "measurement_unit": "г"}, {"name": "фасоль белая лима", "measurement_unit": "г"}, {"name": "фасоль зеленая стручковая", "measurement_unit": "г"}, {"name": "фасоль кенийская", "measurement_unit": "горсть"}, {"name": "фасоль кидни красная", "measurement_unit": "г"}, {"name": "фасоль консервированная", "measurement_unit": "г"}, {"name": "фасоль красная", "measurement_unit": "г"}, {"name": "фасоль красная вареная", "measurement_unit": "стакан"}, {"name": "фасоль красная консервированная", "measurement_unit": "г"}, {"name": "фасоль молодая замороженная", "measurement_unit": "г"}, {"name": "фасоль пинто", "measurement_unit": "г"}, {"name": "фасоль спаржевая вареная", "measurement_unit": "г"}, {"name": "фасоль стручковая", "measurement_unit": "г"}, {"name": "фасоль стручковая замороженная", "measurement_unit": "г"}, {"name": "фасоль стручковая консервированная", "measurement_unit": "г"}, {"name": "фасоль черный глаз", "measurement_unit": "г"}, {"name": "фейхоа", "measurement_unit": "г"}, {"name": "фенхель", "measurement_unit": "г"}, {"name": "фенхель семена", "measurement_unit": "г"}, {"name": "фенхель семена молотые", "measurement_unit": "г"}, {"name": "фестонате", "measurement_unit": "г"}, {"name": "фета", "measurement_unit": "г"}, {"name": "фетаки", "measurement_unit": "г"}, {"name": "фетакса", "measurement_unit": "г"}, {"name": "феттучине", "measurement_unit": "г"}, {"name": "фиалки засахаренные", "measurement_unit": "шт."}, {"name": "фиалковый сироп", "measurement_unit": "г"}, {"name": "физалис", "measurement_unit": "по вкусу"}, {"name": "филе красного окуня", "measurement_unit": "шт."}, {"name": "филе лосося", "measurement_unit": "г"}, {"name": "филе палтуса", "measurement_unit": "шт."}, {"name": "финики", "measurement_unit": "г"}, {"name": "финики без косточек", "measurement_unit": "стакан"}, {"name": "финики иранские", "measurement_unit": "г"}, {"name": "финики иранские без косточек", "measurement_unit": "шт."}, {"name": "фисташки", "measurement_unit": "г"}, {"name": "фисташки очищенные", "measurement_unit": "г"}, {"name": "фисташки очищенные несоленые", "measurement_unit": "горсть"}, {"name": "фисташки рубленые", "measurement_unit": "г"}, {"name": "фисташковая мука", "measurement_unit": "г"}, {"name": "фисташковая паста", "measurement_unit": "г"}, {"name": "фисташковое масло", "measurement_unit": "г"}, {"name": "фокачча", "measurement_unit": "по вкусу"}, {"name": "форель", "measurement_unit": "г"}, {"name": "форель вареная", "measurement_unit": "г"}, {"name": "форель горячего копчения", "measurement_unit": "г"}, {"name": "форель озерная свежая", "measurement_unit": "шт."}, {"name": "форель слабосоленая", "measurement_unit": "г"}, {"name": "форель стейки", "measurement_unit": "шт."}, {"name": "форель филе", "measurement_unit": "г"}, {"name": "форель холодного копчения", "measurement_unit": "г"}, {"name": "фрикадельки", "measurement_unit": "г"}, {"name": "фрукт дракона", "measurement_unit": "шт."}, {"name": "фруктовый сироп", "measurement_unit": "г"}, {"name": "фруктовый сок", "measurement_unit": "г"}, {"name": "фруктовый сок без сахара", "measurement_unit": "стакан"}, {"name": "фруктоза", "measurement_unit": "г"}, {"name": "фрукты", "measurement_unit": "г"}, {"name": "фрукты консервированные", "measurement_unit": "г"}, {"name": "фундук", "measurement_unit": "г"}, {"name": "фундучная мука", "measurement_unit": "г"}, {"name": "фунчоза", "measurement_unit": "г"}, {"name": "халва", "measurement_unit": "г"}, {"name": "халва ванильная", "measurement_unit": "г"}, {"name": "халва подсолнечная", "measurement_unit": "г"}, {"name": "халуми", "measurement_unit": "г"}, {"name": "хамон", "measurement_unit": "г"}, {"name": "хек", "measurement_unit": "г"}, {"name": "хек филе", "measurement_unit": "г"}, {"name": "херес", "measurement_unit": "стакан"}, {"name": "хересный уксус", "measurement_unit": "ч. л."}, {"name": "хлеб", "measurement_unit": "г"}, {"name": "хлеб 7 злаков", "measurement_unit": "батон"}, {"name": "хлеб белый", "measurement_unit": "г"}, {"name": "хлеб белый сухой", "measurement_unit": "г"}, {"name": "хлеб бородинский", "measurement_unit": "кусок"}, {"name": "хлеб датский ржаной", "measurement_unit": "г"}, {"name": "хлеб для сэндвичей", "measurement_unit": "г"}, {"name": "хлебная крошка", "measurement_unit": "г"}, {"name": "хлеб ржаной", "measurement_unit": "г"}, {"name": "хлеб серый", "measurement_unit": "г"}, {"name": "хлеб с кунжутом", "measurement_unit": "кусок"}, {"name": "хлеб цельнозерновой", "measurement_unit": "г"}, {"name": "хлебцы пшенично-ржаные цельнозерновые", "measurement_unit": "г"}, {"name": "хлопья 4 злака", "measurement_unit": "г"}, {"name": "хлопья 5 злаков", "measurement_unit": "г"}, {"name": "хлопья 7 злаков", "measurement_unit": "ст. л."}, {"name": "хлопья быстрого приготовления", "measurement_unit": "стакан"}, {"name": "хлорид кальция", "measurement_unit": "г"}, {"name": "хмели-сунели", "measurement_unit": "г"}, {"name": "хмель", "measurement_unit": "ст. л."}, {"name": "хрен", "measurement_unit": "г"}, {"name": "хрен протертый", "measurement_unit": "г"}, {"name": "хрен со сливками", "measurement_unit": "г"}, {"name": "хурма", "measurement_unit": "г"}, {"name": "хурма спелая", "measurement_unit": "г"}, {"name": "цесарка тушка", "measurement_unit": "г"}, {"name": "цикорий", "measurement_unit": "ч. л."}, {"name": "цитроновые цукаты", "measurement_unit": "горсть"}, {"name": "цитрусовые цукаты", "measurement_unit": "шт."}, {"name": "цитрусовый свежевыжатый сок", "measurement_unit": "мл"}, {"name": "цукаты", "measurement_unit": "г"}, {"name": "цукини", "measurement_unit": "г"}, {"name": "цукини цветы", "measurement_unit": "шт."}, {"name": "цыплята", "measurement_unit": "г"}, {"name": "цыплята-корнишоны", "measurement_unit": "шт."}, {"name": "чабер", "measurement_unit": "г"}, {"name": "чабрец", "measurement_unit": "г"}, {"name": "чабрец сушеный", "measurement_unit": "г"}, {"name": "чай дарджилинг", "measurement_unit": "пакетик"}, {"name": "чай жасминовый", "measurement_unit": "ст. л."}, {"name": "чай зеленый", "measurement_unit": "пакетик"}, {"name": "чай копченый лапсанг сушонг", "measurement_unit": "г"}, {"name": "чай красный", "measurement_unit": "г"}, {"name": "чай ройбуш", "measurement_unit": "ст. л."}, {"name": "чай черный", "measurement_unit": "г"}, {"name": "чай черный крупнолистовой", "measurement_unit": "ч. л."}, {"name": "чай черный со специями", "measurement_unit": "пакет"}, {"name": "чай эрл грей", "measurement_unit": "стакан"}, {"name": "чатни манго", "measurement_unit": "г"}, {"name": "чеддер", "measurement_unit": "г"}, {"name": "черемуха", "measurement_unit": "г"}, {"name": "черемуховая мука", "measurement_unit": "г"}, {"name": "черемша", "measurement_unit": "г"}, {"name": "черешневый джем", "measurement_unit": "г"}, {"name": "черешня", "measurement_unit": "г"}, {"name": "черешня консервированная без косточек", "measurement_unit": "ст. л."}, {"name": "черная смородина", "measurement_unit": "г"}, {"name": "черника", "measurement_unit": "г"}, {"name": "черника замороженная", "measurement_unit": "г"}, {"name": "чернила каракатицы", "measurement_unit": "г"}, {"name": "черничный джем", "measurement_unit": "стакан"}, {"name": "чернослив", "measurement_unit": "г"}, {"name": "чернослив без косточек", "measurement_unit": "г"}, {"name": "чернослив вяленый", "measurement_unit": "г"}, {"name": "чернослив копченый без косточек", "measurement_unit": "г"}, {"name": "черносмородиновое варенье", "measurement_unit": "г"}, {"name": "черносмородиновый джем", "measurement_unit": "г"}, {"name": "чеснок", "measurement_unit": "г"}, {"name": "чеснок молодой", "measurement_unit": "г"}, {"name": "чеснок сушеный", "measurement_unit": "г"}, {"name": "чесночная соль", "measurement_unit": "щепотка"}, {"name": "чесночное масло", "measurement_unit": "по вкусу"}, {"name": "чесночный порошок", "measurement_unit": "г"}, {"name": "чечевица", "measurement_unit": "г"}, {"name": "чечевица вареная", "measurement_unit": "ст. л."}, {"name": "чечевица зеленая", "measurement_unit": "г"}, {"name": "чечевица красная", "measurement_unit": "г"}, {"name": "чечил спагетти", "measurement_unit": "г"}, {"name": "чиабатта", "measurement_unit": "кусок"}, {"name": "чиа семена", "measurement_unit": "г"}, {"name": "чипотле молотый", "measurement_unit": "щепотка"}, {"name": "чипсы", "measurement_unit": "г"}, {"name": "чоризо", "measurement_unit": "г"}, {"name": "шалфей", "measurement_unit": "г"}, {"name": "шалфей свежий", "measurement_unit": "пучок"}, {"name": "шалфей сушеный", "measurement_unit": "лист"}, {"name": "шампанское", "measurement_unit": "г"}, {"name": "шампанское советское", "measurement_unit": "стакан"}, {"name": "шампанское сухое", "measurement_unit": "ст. л."}, {"name": "шампиньоны", "measurement_unit": "по вкусу"}, {"name": "шампиньоны замороженные", "measurement_unit": "г"}, {"name": "шампиньоны консервированные", "measurement_unit": "г"}, {"name": "шампиньоны маринованные", "measurement_unit": "г"}, {"name": "шампиньоны свежие", "measurement_unit": "г"}, {"name": "шафран", "measurement_unit": "г"}, {"name": "шафран имеретинский", "measurement_unit": "г"}, {"name": "шафран молотый", "measurement_unit": "ч. л."}, {"name": "шафран нити", "measurement_unit": "шт."}, {"name": "шелковица", "measurement_unit": "г"}, {"name": "шелковица сушеная", "measurement_unit": "г"}, {"name": "шиповник", "measurement_unit": "г"}, {"name": "шиповниковый сироп", "measurement_unit": "г"}, {"name": "шнапс", "measurement_unit": "г"}, {"name": "шнитт-лук", "measurement_unit": "стебель"}, {"name": "шоколад", "measurement_unit": "г"}, {"name": "шоколад белый", "measurement_unit": "г"}, {"name": "шоколад горький с апельсиновой цедрой", "measurement_unit": "г"}, {"name": "шоколад молочный", "measurement_unit": "г"}, {"name": "шоколад мятный", "measurement_unit": "г"}, {"name": "шоколадная паста", "measurement_unit": "г"}, {"name": "шоколадная стружка", "measurement_unit": "г"}, {"name": "шоколадное масло", "measurement_unit": "г"}, {"name": "шоколадно-ореховая паста", "measurement_unit": "г"}, {"name": "шоколадные горошины", "measurement_unit": "г"}, {"name": "шоколадные капли", "measurement_unit": "г"}, {"name": "шоколадные капли белые", "measurement_unit": "г"}, {"name": "шоколадные конфеты", "measurement_unit": "г"}, {"name": "шоколадные хлопья", "measurement_unit": "г"}, {"name": "шоколадные шарики из готовых завтраков", "measurement_unit": "горсть"}, {"name": "шоколадный ликер", "measurement_unit": "г"}, {"name": "шоколадный сироп", "measurement_unit": "г"}, {"name": "шоколадный соус", "measurement_unit": "г"}, {"name": "шоколад полусладкий", "measurement_unit": "г"}, {"name": "шоколад с орехами", "measurement_unit": "г"}, {"name": "шоколад черный горький", "measurement_unit": "г"}, {"name": "шоколад черный горький 70%", "measurement_unit": "г"}, {"name": "шоколад черный горький 75%", "measurement_unit": "ч. л."}, {"name": "шоколад черный горький 85%", "measurement_unit": "г"}, {"name": "шортенинг", "measurement_unit": "стакан"}, {"name": "шпик", "measurement_unit": "шт."}, {"name": "шпик копченый", "measurement_unit": "г"}, {"name": "шпинат", "measurement_unit": "г"}, {"name": "шпинат замороженный", "measurement_unit": "г"}, {"name": "шпинат молодой", "measurement_unit": "г"}, {"name": "шпинат свежий", "measurement_unit": "г"}, {"name": "шпроты", "measurement_unit": "г"}, {"name": "шпроты в масле", "measurement_unit": "г"}, {"name": "шрот", "measurement_unit": "г"}, {"name": "щавель замороженный", "measurement_unit": "г"}, {"name": "щавель свежий", "measurement_unit": "веточка"}, {"name": "щука", "measurement_unit": "г"}, {"name": "щука филе", "measurement_unit": "г"}, {"name": "эгг-ног", "measurement_unit": "стакан"}, {"name": "эдам", "measurement_unit": "г"}, {"name": "эль", "measurement_unit": "мл"}, {"name": "эмменталь", "measurement_unit": "г"}, {"name": "эскалоп", "measurement_unit": "г"}, {"name": "эстрагон", "measurement_unit": "г"}, {"name": "эстрагон сушеный", "measurement_unit": "веточка"}, {"name": "яблоки", "measurement_unit": "г"}, {"name": "яблоки антоновка", "measurement_unit": "кг"}, {"name": "яблоки гала", "measurement_unit": "г"}, {"name": "яблоки голден", "measurement_unit": "г"}, {"name": "яблоки гренни смит", "measurement_unit": "кг"}, {"name": "яблоки зеленые", "measurement_unit": "г"}, {"name": "яблоки красные", "measurement_unit": "шт."}, {"name": "яблоки моченые", "measurement_unit": "шт."}, {"name": "яблоки нетвердых сортов", "measurement_unit": "г"}, {"name": "яблоки сладкие", "measurement_unit": "г"}, {"name": "яблоки сушеные", "measurement_unit": "г"}, {"name": "яблочная эссенция", "measurement_unit": "ч. л."}, {"name": "яблочное варенье", "measurement_unit": "г"}, {"name": "яблочное повидло", "measurement_unit": "г"}, {"name": "яблочное пюре", "measurement_unit": "г"}, {"name": "яблочные чипсы", "measurement_unit": "стакан"}, {"name": "яблочный джем", "measurement_unit": "г"}, {"name": "яблочный сироп", "measurement_unit": "ст. л."}, {"name": "яблочный сок", "measurement_unit": "г"}, {"name": "яблочный соус", "measurement_unit": "ст. л."}, {"name": "яблочный уксус", "measurement_unit": "г"}, {"name": "ягнятина", "measurement_unit": "г"}, {"name": "ягнятина кострец", "measurement_unit": "г"}, {"name": "ягнятина фарш", "measurement_unit": "г"}, {"name": "ягнячьи отбивные на косточке", "measurement_unit": "шт."}, {"name": "ягнячья голень нарубленная", "measurement_unit": "г"}, {"name": "ягнячья корейка", "measurement_unit": "г"}, {"name": "ягодное варенье", "measurement_unit": "ст. л."}, {"name": "ягодное желе", "measurement_unit": "г"}, {"name": "ягодный сироп", "measurement_unit": "г"}, {"name": "ягодный сок", "measurement_unit": "г"}, {"name": "ягодный соус кислый", "measurement_unit": "г"}, {"name": "ягоды", "measurement_unit": "г"}, {"name": "ягоды вяленые", "measurement_unit": "по вкусу"}, {"name": "ягоды замороженные", "measurement_unit": "г"}, {"name": "ягоды лесные", "measurement_unit": "г"}, {"name": "ягоды лесные замороженные", "measurement_unit": "г"}, {"name": "яичные белки", "measurement_unit": "г"}, {"name": "яичные желтки", "measurement_unit": "г"}, {"name": "яичные желтки вареные", "measurement_unit": "шт."}, {"name": "яичные желтки крупные", "measurement_unit": "г"}, {"name": "яичный меланж", "measurement_unit": "г"}, {"name": "яичный порошок", "measurement_unit": "ст. л."}, {"name": "яйца куриные", "measurement_unit": "г"}, {"name": "яйца куриные крупные", "measurement_unit": "г"}, {"name": "яйца перепелиные", "measurement_unit": "г"}, {"name": "японская крошка панко", "measurement_unit": "г"}, {"name": "ячменные хлопья", "measurement_unit": "г"}, {"name": "ячмень", "measurement_unit": "г"}, {"name": "ячневая крупа", "measurement_unit": "г"}] diff --git a/backend/manage.py b/backend/manage.py new file mode 100644 index 0000000..2c5b9dc --- /dev/null +++ b/backend/manage.py @@ -0,0 +1,21 @@ +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'foodgram.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/backend/recipes/__init__.py b/backend/recipes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/recipes/admin.py b/backend/recipes/admin.py new file mode 100644 index 0000000..b95459d --- /dev/null +++ b/backend/recipes/admin.py @@ -0,0 +1,62 @@ +from import_export.admin import ImportExportActionModelAdmin +from django.contrib import admin +from django.contrib.admin import display + +from recipes.models import (Ingredient, + Tag, + Recipe, + Favorite, + ShoppingCart, + Subscribe, + IngredientAmount, + RecipeTag, + ) +from users.models import User + + +@admin.register(Tag) +class RecipeIngredientAdmin(ImportExportActionModelAdmin): + list_display = ('name',) + list_filter = ('name',) + search_fields = ('name',) + + +@admin.register(Ingredient) +class RecipeTagAdmin(ImportExportActionModelAdmin): + list_display = ('name', 'measurement_unit') + list_filter = ('name',) + search_fields = ('name',) + + +class TagInRecipeAdmin(admin.TabularInline): + model = RecipeTag + autocomplete_fields = ('tag', ) + + +class IngredientAmountAdmin(admin.TabularInline): + model = IngredientAmount + autocomplete_fields = ('ingredient', ) + + +class RecipeAdmin(admin.ModelAdmin): + inlines = (IngredientAmountAdmin, TagInRecipeAdmin) + list_display = ('id', 'name', 'text', 'author', 'is_in_favorites') + readonly_fields = ('is_in_favorites',) + list_filter = ('pub_date', 'author', 'name', 'tags',) + empty_value_display = '-пусто-' + + @display(description='Добавлено в избранное') + def is_in_favorites(self, obj): + return obj.favorites_recipes.count() + + +class UserAdmin(admin.ModelAdmin): + list_display = ('email', 'username', 'first_name', 'last_name',) + list_filter = ('email', 'username',) + + +admin.site.register(Recipe, RecipeAdmin) +admin.site.register(Favorite) +admin.site.register(ShoppingCart) +admin.site.register(User, UserAdmin) +admin.site.register(Subscribe) diff --git a/backend/recipes/apps.py b/backend/recipes/apps.py new file mode 100644 index 0000000..3b0e048 --- /dev/null +++ b/backend/recipes/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class RecipesConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'recipes' diff --git a/backend/recipes/migrations/0001_initial.py b/backend/recipes/migrations/0001_initial.py new file mode 100644 index 0000000..8525517 --- /dev/null +++ b/backend/recipes/migrations/0001_initial.py @@ -0,0 +1,116 @@ +# Generated by Django 4.2.4 on 2023-09-23 11:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Favorite', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'verbose_name': 'Избранное', + 'verbose_name_plural': 'Избранное', + 'ordering': ['recipe'], + }, + ), + migrations.CreateModel( + name='Ingredient', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150, verbose_name='Название ингредиента')), + ('measurement_unit', models.CharField(max_length=150, verbose_name='Единица измерения')), + ], + options={ + 'verbose_name': 'Ингредиент', + 'verbose_name_plural': 'Ингредиенты', + 'db_table': 'recipes_ingredient', + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='IngredientAmount', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.PositiveIntegerField(default=1, verbose_name='Количество')), + ], + ), + migrations.CreateModel( + name='Recipe', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100, verbose_name='Название рецепта')), + ('image', models.ImageField(blank=True, upload_to='recipes/', verbose_name='Картинка')), + ('text', models.TextField(help_text='Введите текст рецепта', verbose_name='Текст рецепта')), + ('cooking_time', models.PositiveSmallIntegerField(default=1, verbose_name='Время приготовления')), + ('pub_date', models.DateTimeField(auto_now_add=True, verbose_name='Дата публикации')), + ], + options={ + 'verbose_name': 'Рецепт', + 'verbose_name_plural': 'Рецепты', + 'ordering': ['-pub_date'], + }, + ), + migrations.CreateModel( + name='RecipeIngredient', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.PositiveSmallIntegerField(verbose_name='Количество')), + ], + options={ + 'ordering': ['recipe'], + }, + ), + migrations.CreateModel( + name='RecipeTag', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'ordering': ['recipe'], + }, + ), + migrations.CreateModel( + name='ShoppingCart', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'verbose_name': 'Список покупок', + 'verbose_name_plural': 'Списки покупок', + 'ordering': ['recipe'], + }, + ), + migrations.CreateModel( + name='Subscribe', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + options={ + 'ordering': ['author'], + }, + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150, unique=True, verbose_name='Название тега')), + ('color', models.CharField(max_length=10, unique=True, verbose_name='Цветовой код')), + ('slug', models.SlugField(unique=True, verbose_name='Слаг')), + ], + options={ + 'verbose_name': 'Тег', + 'verbose_name_plural': 'Теги', + 'db_table': 'recipes_tag', + 'ordering': ['name'], + }, + ), + ] diff --git a/backend/recipes/migrations/0002_initial.py b/backend/recipes/migrations/0002_initial.py new file mode 100644 index 0000000..57f8083 --- /dev/null +++ b/backend/recipes/migrations/0002_initial.py @@ -0,0 +1,93 @@ +# Generated by Django 4.2.4 on 2023-09-23 11:09 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('recipes', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='subscribe', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscribing', to=settings.AUTH_USER_MODEL, verbose_name='Автор'), + ), + migrations.AddField( + model_name='subscribe', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscriber', to=settings.AUTH_USER_MODEL, verbose_name='Подписчик'), + ), + migrations.AddField( + model_name='shoppingcart', + name='recipe', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shopping_cart', to='recipes.recipe', verbose_name='Рецепт'), + ), + migrations.AddField( + model_name='shoppingcart', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shopping_cart', to=settings.AUTH_USER_MODEL, verbose_name='Пользователь'), + ), + migrations.AddField( + model_name='recipetag', + name='recipe', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipe_in_tags', to='recipes.recipe'), + ), + migrations.AddField( + model_name='recipetag', + name='tag', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tag_in_recipes', to='recipes.tag'), + ), + migrations.AddField( + model_name='recipeingredient', + name='ingredient', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ingr_in_recipes', to='recipes.ingredient'), + ), + migrations.AddField( + model_name='recipeingredient', + name='recipe', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipe_in_ingr', to='recipes.recipe'), + ), + migrations.AddField( + model_name='recipe', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipes', to=settings.AUTH_USER_MODEL, verbose_name='Автор'), + ), + migrations.AddField( + model_name='recipe', + name='ingredients', + field=models.ManyToManyField(related_name='recipes', to='recipes.ingredient', verbose_name='Название ингредиента'), + ), + migrations.AddField( + model_name='recipe', + name='tags', + field=models.ManyToManyField(related_name='recipes', to='recipes.tag', verbose_name='Теги'), + ), + migrations.AddField( + model_name='ingredientamount', + name='ingredient', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ingredient', to='recipes.ingredient'), + ), + migrations.AddField( + model_name='ingredientamount', + name='recipe', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipe', to='recipes.recipe'), + ), + migrations.AddField( + model_name='favorite', + name='recipe', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='favorites_recipes', to='recipes.recipe', verbose_name='Рецепт'), + ), + migrations.AddField( + model_name='favorite', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='favorites', to=settings.AUTH_USER_MODEL, verbose_name='Пользователь'), + ), + ] diff --git a/backend/recipes/migrations/0003_alter_ingredientamount_amount_and_more.py b/backend/recipes/migrations/0003_alter_ingredientamount_amount_and_more.py new file mode 100644 index 0000000..cf70e4f --- /dev/null +++ b/backend/recipes/migrations/0003_alter_ingredientamount_amount_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.4 on 2023-09-23 16:16 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('recipes', '0002_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='ingredientamount', + name='amount', + field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='Количество'), + ), + migrations.AlterField( + model_name='recipe', + name='cooking_time', + field=models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='Время приготовления'), + ), + migrations.AlterField( + model_name='recipeingredient', + name='amount', + field=models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1)], verbose_name='Количество'), + ), + ] diff --git a/backend/recipes/migrations/__init__.py b/backend/recipes/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/recipes/models.py b/backend/recipes/models.py new file mode 100644 index 0000000..ff334ab --- /dev/null +++ b/backend/recipes/models.py @@ -0,0 +1,220 @@ +from django.db import models +from django.core import validators + +from users.models import User + + +class Ingredient(models.Model): + """Модель ингредиента.""" + name = models.CharField(max_length=150, + verbose_name='Название ингредиента') + measurement_unit = models.CharField(max_length=150, + verbose_name='Единица измерения') + + class Meta: + verbose_name = 'Ингредиент' + verbose_name_plural = 'Ингредиенты' + ordering = ['name'] + db_table = 'recipes_ingredient' + + def __str__(self): + return f'{self.name}, {self.measurement_unit}' + + +class Tag(models.Model): + """Модель тега.""" + name = models.CharField(max_length=150, unique=True, + verbose_name='Название тега') + color = models.CharField(max_length=10, unique=True, + verbose_name='Цветовой код') + slug = models.SlugField(unique=True, verbose_name='Слаг') + + class Meta: + ordering = ['name'] + verbose_name = 'Тег' + verbose_name_plural = 'Теги' + db_table = 'recipes_tag' + + def __str__(self): + return self.name + + +class Recipe(models.Model): + """Модель рецепта.""" + tags = models.ManyToManyField( + Tag, + related_name='recipes', + verbose_name='Теги', + ) + author = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name='recipes', + verbose_name='Автор', + ) + name = models.CharField( + max_length=100, + verbose_name='Название рецепта', + ) + image = models.ImageField( + 'Картинка', + upload_to='recipes/', + blank=True + ) + text = models.TextField(verbose_name='Текст рецепта', + help_text='Введите текст рецепта', + ) + ingredients = models.ManyToManyField( + Ingredient, + related_name='recipes', + verbose_name='Название ингредиента', + ) + cooking_time = models.PositiveSmallIntegerField( + verbose_name='Время приготовления', + default=1, + validators=[validators.MinValueValidator(1)]) + pub_date = models.DateTimeField( + verbose_name='Дата публикации', + auto_now_add=True + ) + + class Meta: + ordering = ['-pub_date'] + verbose_name = 'Рецепт' + verbose_name_plural = 'Рецепты' + + def __str__(self): + return self.name + + +class RecipeIngredient(models.Model): + """ + Вспомогательная модель. + Для реализаци связи М2М между моделями Recipe + и Ingredient. + """ + recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, + related_name='recipe_in_ingr') + ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE, + related_name='ingr_in_recipes') + amount = models.PositiveSmallIntegerField( + 'Количество', + default=1, + validators=[validators.MinValueValidator(1)] + ) + + class Meta: + ordering = ['recipe'] + + def __str__(self): + return f'В {self.recipe} есть {self.ingredient}' + + +class RecipeTag(models.Model): + """ + Вспомогательная модель. + Для реализаци связи М2М между моделями Recipe + и Tag. + """ + recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, + related_name='recipe_in_tags') + tag = models.ForeignKey(Tag, on_delete=models.CASCADE, + related_name='tag_in_recipes') + + class Meta: + ordering = ['recipe'] + + def __str__(self): + return f'Рецепт {self.recipe} отмечен тегом {self.tag}' + + +class Favorite(models.Model): + """Модель избранного.""" + user = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name='favorites', + verbose_name='Пользователь', + ) + recipe = models.ForeignKey( + Recipe, + on_delete=models.CASCADE, + related_name='favorites_recipes', + verbose_name='Рецепт', + ) + + class Meta: + ordering = ['recipe'] + verbose_name = 'Избранное' + verbose_name_plural = 'Избранное' + models.UniqueConstraint(fields=['user', 'recipe'], + name='unique_u_f') + + def __str__(self): + return f'Рецепт {self.recipe} в избранном у {self.user}' + + +class ShoppingCart(models.Model): + """Модель корзины покупок.""" + user = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name='shopping_cart', + verbose_name='Пользователь', + ) + recipe = models.ForeignKey( + Recipe, + on_delete=models.CASCADE, + related_name='shopping_cart', + verbose_name='Рецепт', + ) + + class Meta: + ordering = ['recipe'] + verbose_name = 'Список покупок' + verbose_name_plural = 'Списки покупок' + models.UniqueConstraint(fields=['user', 'recipe'], + name='unique_s_l') + + def __str__(self): + return f'Рецепт {self.recipe} в списке покупок у {self.user}' + + +class Subscribe(models.Model): + """Модель подписки.""" + user = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name='subscriber', + verbose_name='Подписчик' + ) + author = models.ForeignKey( + User, + on_delete=models.CASCADE, + related_name='subscribing', + verbose_name='Автор' + ) + + class Meta: + ordering = ['author'] + models.UniqueConstraint(fields=['user', 'author'], + name='unique_ua') + + +class IngredientAmount(models.Model): + """Модель вывода количества ингредиенто в рецепте.""" + recipe = models.ForeignKey( + Recipe, + on_delete=models.CASCADE, + related_name='recipe', + ) + ingredient = models.ForeignKey( + Ingredient, + on_delete=models.CASCADE, + related_name='ingredient', + ) + amount = models.PositiveIntegerField( + 'Количество', + default=1, + validators=[validators.MinValueValidator(1)] + ) diff --git a/backend/recipes/resources.py b/backend/recipes/resources.py new file mode 100644 index 0000000..42352f2 --- /dev/null +++ b/backend/recipes/resources.py @@ -0,0 +1,12 @@ +from import_export import resources +from recipes.models import Ingredient, Tag + + +class RecipesIngredient(resources.ModelResource): + class Meta: + model = Ingredient + + +class RecipesTag(resources.ModelResource): + class Meta: + model = Tag diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..c4751e5 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,12 @@ +Django==3.2.3 +djoser==2.1.0 +webcolors==1.11.1 +psycopg2-binary==2.9.3 +Pillow==9.0.0 +PyYAML==6.0 +python-dotenv==1.0.0 +gunicorn==20.1.0 +requests==2.26.0 +django-import-export==3.2.0 +django-filter==23.2 +reportlab==4.0.4 diff --git a/backend/tags.json b/backend/tags.json new file mode 100644 index 0000000..35d0a0b --- /dev/null +++ b/backend/tags.json @@ -0,0 +1,7 @@ +[ + {"name": "Завтрак", "color": "#7FFF00", "slug": "breakfast"}, + {"name": "Обед", "color": "#00FFFF", "slug": "lunch"}, + {"name": "Ужин", "color": "#0000FF", "slug": "dinner"}, + {"name": "Десерт", "color": "#FF00FF", "slug": "desert"}, + {"name": "Перекус", "color": "#FFD700", "slug": "snack"} +] \ No newline at end of file diff --git a/backend/users/__init__.py b/backend/users/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/users/apps.py b/backend/users/apps.py new file mode 100644 index 0000000..72b1401 --- /dev/null +++ b/backend/users/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class UsersConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'users' diff --git a/backend/users/migrations/0001_initial.py b/backend/users/migrations/0001_initial.py new file mode 100644 index 0000000..8348c2e --- /dev/null +++ b/backend/users/migrations/0001_initial.py @@ -0,0 +1,43 @@ +# Generated by Django 4.2.4 on 2023-09-23 11:09 + +import django.contrib.auth.models +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('email', models.EmailField(max_length=100, unique=True, verbose_name='email address')), + ('username', models.CharField(max_length=40)), + ('first_name', models.CharField(max_length=40)), + ('last_name', models.CharField(max_length=40)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'Пользователь', + 'verbose_name_plural': 'Пользователи', + 'ordering': ['id'], + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + ] diff --git a/backend/users/migrations/__init__.py b/backend/users/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/users/models.py b/backend/users/models.py new file mode 100644 index 0000000..c3e442d --- /dev/null +++ b/backend/users/models.py @@ -0,0 +1,29 @@ +from django.db import models +from django.contrib.auth.models import AbstractUser + + +class User(AbstractUser): + """Абстрактная модель пользователя.""" + email = models.EmailField( + verbose_name='email address', + max_length=100, + unique=True, + ) + username = models.CharField(max_length=40) + first_name = models.CharField(max_length=40) + last_name = models.CharField(max_length=40) + + USERNAME_FIELD = 'email' + REQUIRED_FIELDS = [ + 'username', + 'first_name', + 'last_name', + ] + + class Meta: + ordering = ['id'] + verbose_name = 'Пользователь' + verbose_name_plural = 'Пользователи' + + def __str__(self): + return self.username diff --git a/docker-compose.production.yml b/docker-compose.production.yml new file mode 100644 index 0000000..a31963d --- /dev/null +++ b/docker-compose.production.yml @@ -0,0 +1,44 @@ +version: '3.8' + +volumes: + fg_data: + static_fg: + media_fg: + + +services: + db: + image: postgres:13 + env_file: .env + volumes: + - fg_data:/var/lib/postgresql/data + backend: + image: zebrahr/foodgram_backend + restart: always + env_file: .env + depends_on: + - db + volumes: + - static_fg:/backend_static + - media_fg:/app/media + frontend: + image: zebrahr/foodgram_frontend + volumes: + - ./frontend/:/app/result_build/ + depends_on: + - db + - backend + nginx: + image: nginx:1.19.3 + ports: + - "8000:80" + volumes: + - ./infra/nginx.conf:/etc/nginx/conf.d/default.conf + - ./frontend/build:/usr/share/nginx/html/ + - ./docs/:/usr/share/nginx/html/api/docs/ + - static_fg:/staticfiles/ + - media_fg:/app/media/ + depends_on: + - backend + - frontend + \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c84975a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,47 @@ +version: '3.8' +name: food +volumes: + fg_data: + static_fg: + media_fg: + +services: + db: + image: postgres:13 + env_file: .env + volumes: + - fg_data:/var/lib/postgresql/fg_data + backend: + build: + context: ./backend + dockerfile: Dockerfile + # restart: always + env_file: .env + depends_on: + - db + volumes: + - static_fg:/backend_static + - media_fg:/app/media + # - ./backend/foodgram:/app/foodgram + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + volumes: + - ./frontend/:/app/result_build/ + depends_on: + - db + - backend + nginx: + image: nginx:1.19.3 + ports: + - "8000:80" + volumes: + - ./infra/nginx.conf:/etc/nginx/conf.d/default.conf + - ./frontend/build:/usr/share/nginx/html/ + - ./docs/:/usr/share/nginx/html/api/docs/ + - static_fg:/staticfiles/ + - media_fg:/app/media/ + depends_on: + - backend + \ No newline at end of file diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml index de894f6..189026e 100644 --- a/infra/docker-compose.yml +++ b/infra/docker-compose.yml @@ -1,17 +1,43 @@ -version: '3.3' -services: +version: '3.8' +name: food +volumes: + fg_data: + static_fg: + media_fg: +services: + db: + image: postgres:13 + env_file: .env + backend: + build: + context: ./backend + dockerfile: Dockerfile + restart: always + env_file: .env + depends_on: + - db + volumes: + - static:/app/backend_static + - media:/app/media frontend: build: - context: ../frontend + context: ./frontend dockerfile: Dockerfile volumes: - - ../frontend/:/app/result_build/ + - ./frontend/:/app/result_build/ + depends_on: + - db nginx: image: nginx:1.19.3 ports: - - "80:80" + - "8000:80" volumes: - - ./nginx.conf:/etc/nginx/conf.d/default.conf - - ../frontend/build:/usr/share/nginx/html/ - - ../docs/:/usr/share/nginx/html/api/docs/ + - ./infra/nginx.conf:/etc/nginx/conf.d/default.conf + - ./frontend/build:/usr/share/nginx/html/ + - ./docs/:/usr/share/nginx/html/api/docs/ + - static_fg: /etc/nginx/html/static/ + - media_fg: /etc/nginx/html/media/ + depends_on: + - backend + \ No newline at end of file diff --git a/infra/nginx.conf b/infra/nginx.conf index 68a2099..93e6b14 100644 --- a/infra/nginx.conf +++ b/infra/nginx.conf @@ -1,21 +1,48 @@ -server { +server { + server_tokens off; listen 80; - location /api/docs/ { - root /usr/share/nginx/html; - try_files $uri $uri/redoc.html; - } - location / { - root /usr/share/nginx/html; - index index.html index.htm; - try_files $uri /index.html; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } - error_page 500 502 503 504 /50x.html; - location = /50x.html { - root /var/html/frontend/; - } + client_max_body_size 30M; + + location /api/docs/ { + root /usr/share/nginx/html; + try_files $uri $uri/redoc.html; + } + + location /api/ { + proxy_set_header Host $http_host; + proxy_pass http://backend:8000/api/; + } + + location /admin/ { + proxy_set_header Host $http_host; + proxy_pass http://backend:8000/admin/; + } -} + location /media/ { + proxy_set_header Host $http_host; + alias /app/media/; + } + + location /static/admin { + root /staticfiles/; + } + + location /static/rest_framework/ { + root /staticfiles/; + } + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri /index.html; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /var/html/frontend/; + } + +} \ No newline at end of file diff --git a/setup copy.cfg b/setup copy.cfg new file mode 100644 index 0000000..f281e4b --- /dev/null +++ b/setup copy.cfg @@ -0,0 +1,16 @@ +[flake8] +# Не проверять код на соответствие стандартам W503 и F811 +ignore = + W503, + F811 +# Не проверять код в перечисленных директориях: +exclude = + tests/, + */migrations/, + venv/, + */venv/, + env/ + */env/, +# Не проверять указанные файлы на соответствие определённым правилам: +per-file-ignores = + */settings.py:E501 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..f281e4b --- /dev/null +++ b/setup.cfg @@ -0,0 +1,16 @@ +[flake8] +# Не проверять код на соответствие стандартам W503 и F811 +ignore = + W503, + F811 +# Не проверять код в перечисленных директориях: +exclude = + tests/, + */migrations/, + venv/, + */venv/, + env/ + */env/, +# Не проверять указанные файлы на соответствие определённым правилам: +per-file-ignores = + */settings.py:E501 \ No newline at end of file