Skip to content

Commit a477043

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

File tree

2 files changed

+58
-36
lines changed

2 files changed

+58
-36
lines changed

backend/foodgram/foodapp/admin.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,69 @@
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+
tags = cleaned_data.get('tags')
38+
if not tags or not tags.exists():
39+
raise ValidationError(
40+
{'tags': 'Необходимо указать хотя бы один тег.'})
41+
42+
instance = self.instance
43+
if instance.pk:
44+
if not RecipeIngredient.objects.filter(recipe=instance).exists():
45+
raise ValidationError({
46+
'recipe_ingredients': 'Список '
47+
'ингредиентов не может быть '
48+
'пустым.'})
49+
50+
ingredients_ids_set = set()
51+
for ri in RecipeIngredient.objects.filter(recipe=instance):
52+
ingredient_id = ri.ingredient.id
53+
if ingredient_id in ingredients_ids_set:
54+
raise ValidationError({
55+
'recipe_ingredients': 'Ингредиенты не должны '
56+
'повторяться.'})
57+
if ri.amount < INGREDIENT_MIN_AMOUNT:
58+
raise ValidationError({
59+
'recipe_ingredients': f'Минимальное количество '
60+
f'ингредиента: '
61+
f'{INGREDIENT_MIN_AMOUNT}'})
62+
ingredients_ids_set.add(ingredient_id)
63+
64+
return cleaned_data
65+
66+
1167
@admin.register(User)
1268
class FoodgramUserAdmin(UserAdmin):
1369
"""Админка для пользователей."""
@@ -39,6 +95,7 @@ class RecipeIngredientInline(admin.TabularInline):
3995
@admin.register(Recipe)
4096
class RecipeAdmin(admin.ModelAdmin):
4197
"""Админка для рецептов."""
98+
form = RecipeAdminForm
4299
list_display = ('id', 'name', 'author',
43100
'get_tags', 'favorite_count')
44101
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)