|
| 1 | +from django import forms |
1 | 2 | from django.contrib import admin |
2 | 3 | from django.contrib.auth import get_user_model |
3 | 4 | from django.contrib.auth.admin import UserAdmin |
| 5 | +from django.core.exceptions import ValidationError |
4 | 6 |
|
| 7 | +from .constants import INGREDIENT_MIN_AMOUNT, MIN_COOKING_TIME |
5 | 8 | from .models import (Favorite, Ingredient, Recipe, RecipeIngredient, |
6 | 9 | ShoppingCart, Tag) |
7 | 10 |
|
8 | 11 | User = get_user_model() |
9 | 12 |
|
10 | 13 |
|
| 14 | +class RecipeAdminForm(forms.ModelForm): |
| 15 | + """Проверка на: |
| 16 | + - минимальное допустимое время приготовления рецепта |
| 17 | + - наличие тегов |
| 18 | + - наличие ингредиентов |
| 19 | + - отсутствие повторяющихся ингредиентов |
| 20 | + - минимальное количество ингредиента |
| 21 | + при добавлении рецепта через админ панель. |
| 22 | + """ |
| 23 | + |
| 24 | + class Meta: |
| 25 | + model = Recipe |
| 26 | + exclude = ('hashcode',) |
| 27 | + |
| 28 | + def clean(self): |
| 29 | + cleaned_data = super().clean() |
| 30 | + |
| 31 | + cooking_time = cleaned_data.get('cooking_time') |
| 32 | + if cooking_time is None or cooking_time < MIN_COOKING_TIME: |
| 33 | + raise ValidationError({ |
| 34 | + 'cooking_time': f'Минимальное время ' |
| 35 | + f'приготовления: {MIN_COOKING_TIME}'}) |
| 36 | + |
| 37 | + tags = cleaned_data.get('tags') |
| 38 | + if not tags or not tags.exists(): |
| 39 | + raise ValidationError( |
| 40 | + {'tags': 'Необходимо указать хотя бы один тег.'}) |
| 41 | + |
| 42 | + ingredients_list = self.data.getlist('recipe_ingredients') |
| 43 | + if not ingredients_list: |
| 44 | + raise ValidationError( |
| 45 | + {'recipe_ingredients': 'Список ингредиентов ' |
| 46 | + 'не может быть пустым.'}) |
| 47 | + |
| 48 | + ingredients_ids_set = set() |
| 49 | + for ingredient_data in ingredients_list: |
| 50 | + ingredient_id, amount = map(int, ingredient_data.split(",")) |
| 51 | + if ingredient_id in ingredients_ids_set: |
| 52 | + raise ValidationError({ |
| 53 | + 'recipe_ingredients': 'Ингредиенты не должны повторяться.' |
| 54 | + }) |
| 55 | + if amount < INGREDIENT_MIN_AMOUNT: |
| 56 | + raise ValidationError({ |
| 57 | + 'recipe_ingredients': f'Минимальное кол-во ингредиента: ' |
| 58 | + f'{INGREDIENT_MIN_AMOUNT}'}) |
| 59 | + ingredients_ids_set.add(ingredient_id) |
| 60 | + |
| 61 | + return cleaned_data |
| 62 | + |
| 63 | + |
11 | 64 | @admin.register(User) |
12 | 65 | class FoodgramUserAdmin(UserAdmin): |
13 | 66 | """Админка для пользователей.""" |
@@ -39,6 +92,7 @@ class RecipeIngredientInline(admin.TabularInline): |
39 | 92 | @admin.register(Recipe) |
40 | 93 | class RecipeAdmin(admin.ModelAdmin): |
41 | 94 | """Админка для рецептов.""" |
| 95 | + form = RecipeAdminForm |
42 | 96 | list_display = ('id', 'name', 'author', |
43 | 97 | 'get_tags', 'favorite_count') |
44 | 98 | search_fields = ('name', 'author__username') |
|
0 commit comments