Skip to content

Commit 0cfef35

Browse files
committed
Remove clean() from Recipe model as validation now is handled in forms
1 parent 8becabd commit 0cfef35

File tree

2 files changed

+55
-36
lines changed

2 files changed

+55
-36
lines changed

backend/foodgram/foodapp/admin.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,66 @@
1+
from django import forms
12
from django.contrib import admin
23
from django.contrib.auth import get_user_model
34
from django.contrib.auth.admin import UserAdmin
5+
from django.core.exceptions import ValidationError
46

7+
from .constants import INGREDIENT_MIN_AMOUNT, MIN_COOKING_TIME
58
from .models import (Favorite, Ingredient, Recipe, RecipeIngredient,
69
ShoppingCart, Tag)
710

811
User = get_user_model()
912

1013

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+
1164
@admin.register(User)
1265
class FoodgramUserAdmin(UserAdmin):
1366
"""Админка для пользователей."""
@@ -39,6 +92,7 @@ class RecipeIngredientInline(admin.TabularInline):
3992
@admin.register(Recipe)
4093
class RecipeAdmin(admin.ModelAdmin):
4194
"""Админка для рецептов."""
95+
form = RecipeAdminForm
4296
list_display = ('id', 'name', 'author',
4397
'get_tags', 'favorite_count')
4498
search_fields = ('name', 'author__username')

backend/foodgram/foodapp/models.py

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
from django.conf import settings
44
from django.contrib.auth import get_user_model
55
from django.contrib.auth.models import AbstractUser
6-
from django.core.exceptions import ValidationError
76
from django.core.validators import RegexValidator
87
from django.db import models
98

10-
from .constants import (INGREDIENT_MIN_AMOUNT, INGREDIENT_NAME_MAX_LEN,
11-
MEASUREMENT_UNIT_MAX_LEN, MIN_COOKING_TIME,
9+
from .constants import (INGREDIENT_NAME_MAX_LEN, MEASUREMENT_UNIT_MAX_LEN,
1210
RECIPE_HASHCODE_MAX_LEN, RECIPE_NAME_MAX_LEN,
1311
TAG_NAME_MAX_LEN, TAG_SLUG_MAX_LEN,
1412
USER_FIRST_NAME_MAX_LEN, USER_LAST_NAME_MAX_LEN,
@@ -100,39 +98,6 @@ class Meta:
10098
verbose_name_plural = 'Рецепты'
10199
ordering = ('-created_at',)
102100

103-
def clean(self):
104-
"""Проверка на:
105-
- наличие тегов
106-
- минимальное допустимое время приготовления рецепта
107-
- отсутствие повторяющихся ингредиентов
108-
- минимальное количество ингредиента
109-
при добавлении рецепта через админ панель.
110-
"""
111-
if self.cooking_time < MIN_COOKING_TIME:
112-
raise ValidationError({
113-
'cooking_time': f'Минимальное время '
114-
f'приготовления: {MIN_COOKING_TIME}'})
115-
if not self.pk and not self.tags.count():
116-
raise ValidationError(
117-
{'tags': 'Необходимо указать хотя бы один тег.'})
118-
if not self.recipe_ingredients.exists():
119-
raise ValidationError(
120-
{'recipe_ingredients': 'Список ингредиентов '
121-
'не может быть пустым.'})
122-
123-
ingredients_ids_set = set()
124-
for ingredient in self.recipe_ingredients.all():
125-
ingredient_id = ingredient.ingredient.id
126-
if ingredient_id in ingredients_ids_set:
127-
raise ValidationError(
128-
{'recipe_ingredients': 'Ингредиенты не должны '
129-
'повторяться.'})
130-
if ingredient.amount < INGREDIENT_MIN_AMOUNT:
131-
raise ValidationError(
132-
{'recipe_ingredients': f'Минимальное кол-во ингредиента: '
133-
f'{INGREDIENT_MIN_AMOUNT}'})
134-
ingredients_ids_set.add(ingredient_id)
135-
136101
def __str__(self):
137102
return self.name
138103

0 commit comments

Comments
 (0)