Skip to content

Commit 82cbc24

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

File tree

2 files changed

+59
-37
lines changed

2 files changed

+59
-37
lines changed

backend/foodgram/foodapp/admin.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,68 @@
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+
fields = '__all__'
27+
28+
def clean(self):
29+
cleaned_data = super().clean()
30+
31+
cooking_time = cleaned_data.get("cooking_time")
32+
if cooking_time and cooking_time < MIN_COOKING_TIME:
33+
raise ValidationError({
34+
'cooking_time': f'Минимальное время '
35+
f'приготовления: {MIN_COOKING_TIME}'})
36+
37+
if not cleaned_data.get("tags").exists():
38+
raise ValidationError(
39+
{'tags': 'Необходимо указать хотя бы один тег.'})
40+
41+
instance = self.instance
42+
if instance.pk:
43+
if not RecipeIngredient.objects.filter(recipe=instance).exists():
44+
raise ValidationError({
45+
'recipe_ingredients': 'Список '
46+
'ингредиентов не может быть '
47+
'пустым.'})
48+
49+
ingredients_ids_set = set()
50+
for ri in RecipeIngredient.objects.filter(recipe=instance):
51+
ingredient_id = ri.ingredient.id
52+
if ingredient_id in ingredients_ids_set:
53+
raise ValidationError({
54+
'recipe_ingredients': 'Ингредиенты не должны '
55+
'повторяться.'})
56+
if ri.amount < INGREDIENT_MIN_AMOUNT:
57+
raise ValidationError({
58+
'recipe_ingredients': f'Минимальное количество '
59+
f'ингредиента: '
60+
f'{INGREDIENT_MIN_AMOUNT}'})
61+
ingredients_ids_set.add(ingredient_id)
62+
63+
return cleaned_data
64+
65+
1166
@admin.register(User)
1267
class FoodgramUserAdmin(UserAdmin):
1368
"""Админка для пользователей."""
@@ -39,6 +94,7 @@ class RecipeIngredientInline(admin.TabularInline):
3994
@admin.register(Recipe)
4095
class RecipeAdmin(admin.ModelAdmin):
4196
"""Админка для рецептов."""
97+
form = RecipeAdminForm
4298
list_display = ('id', 'name', 'author',
4399
'get_tags', 'favorite_count')
44100
search_fields = ('name', 'author__username')

backend/foodgram/foodapp/models.py

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
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,
12-
RECIPE_HASHCODE_MAX_LEN, RECIPE_NAME_MAX_LEN,
9+
from .constants import (INGREDIENT_NAME_MAX_LEN,
10+
MEASUREMENT_UNIT_MAX_LEN, RECIPE_HASHCODE_MAX_LEN,
11+
RECIPE_NAME_MAX_LEN,
1312
TAG_NAME_MAX_LEN, TAG_SLUG_MAX_LEN,
1413
USER_FIRST_NAME_MAX_LEN, USER_LAST_NAME_MAX_LEN,
1514
USER_USERNAME_MAX_LEN)
@@ -100,39 +99,6 @@ class Meta:
10099
verbose_name_plural = 'Рецепты'
101100
ordering = ('-created_at',)
102101

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-
136102
def __str__(self):
137103
return self.name
138104

0 commit comments

Comments
 (0)