🏠 Практика: закрепление сериализаторов DRF
Информация: Это не LMS-домашнее задание. Это закрепляющее задание для самостоятельной практики по теме урока. Выполняется локально, проверяется через DRF Browsable API и Postman.
⚡ Задача для самостоятельной практики
Расширить сериализаторы store-приложения:
- Добавить
validate_emailвCustomerCreateUpdateSerializer— проверить формат email через regex - Создать
ProductListSerializer— только поляid,name,priceдля списка - Добавить кросс-полевую валидацию в
OrderItemCreateUpdateSerializer— если quantity > 0
Проверка: python manage.py shell → импорт сериализаторов → тест с данными.
Подготовка окружения
1. Создание виртуального окружения
# Windows PowerShell
python -m venv venv
.\venv\Scripts\Activate.ps1
# Установка зависимостей
pip install django djangorestframework
2. Структура проекта
myshop/
├── manage.py
├── myshop/
│ ├── settings.py
│ └── urls.py
└── store/
├── models.py
├── serializers.py <-- основной файл
└── views.py
3. Базовые настройки settings.py
INSTALLED_APPS = [
...
'rest_framework',
'store',
]
Задание 1: Валидация email в CustomerCreateUpdateSerializer
Добавить метод validate_email, который проверяет, что email содержит символ @ и точку после него.
# store/serializers.py
import re
class CustomerCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = ['first_name', 'last_name', 'email', 'phone_number', 'address']
def validate_phone_number(self, value):
if not re.match(r'^\d{10,15}$', value):
raise serializers.ValidationError(
'Номер телефона должен содержать от 10 до 15 цифр.'
)
return value
def validate_email(self, value):
# Ваш код здесь
# Подсказка: проверьте наличие @ и точки после него
pass
Задание 2: ProductListSerializer — сокращённый список
Для API, который отдаёт список продуктов (например, для каталога), нет смысла возвращать все поля. Создайте ProductListSerializer только с полями id, name, price.
# Ваш код: ProductListSerializer
# fields = ['id', 'name', 'price']
Задание 3: Кросс-полевая валидация OrderItem
Добавить общий метод validate в OrderItemCreateUpdateSerializer, который проверяет что quantity больше нуля:
def validate(self, data):
# Проверить: data['quantity'] > 0
# Подсказка: raise serializers.ValidationError({'quantity': '...'})
pass
Пошаговое решение Задания 1
import re
def validate_email(self, value):
"""Email должен содержать @ и точку в домене."""
if not re.match(r'^[^@]+@[^@]+\.[^@]+$', value):
raise serializers.ValidationError(
'Введите корректный адрес электронной почты.'
)
return value
Пояснение regex:
^[^@]+— один или более символов до @@— знак @[^@]+— один или более символов (доменное имя)\.— буквальная точка[^@]+$— один или более символов (TLD: .com, .ru)
Проверка через Django shell
python manage.py shell
from store.serializers import CustomerCreateUpdateSerializer
# Тест корректных данных
data = {
'first_name': 'Ivan',
'last_name': 'Petrov',
'email': 'ivan@example.com',
'phone_number': '79991234567',
'address': 1
}
s = CustomerCreateUpdateSerializer(data=data)
print(s.is_valid()) # True
# Тест некорректного телефона
data['phone_number'] = '+7 999 123-45-67'
s = CustomerCreateUpdateSerializer(data=data)
print(s.is_valid()) # False
print(s.errors) # {'phone_number': ['...']}
# Тест некорректного email
data['phone_number'] = '79991234567'
data['email'] = 'not-an-email'
s = CustomerCreateUpdateSerializer(data=data)
print(s.is_valid()) # False
print(s.errors) # {'email': ['...']}
exit()
Проверка через DRF Browsable API
- Запустите сервер:
python manage.py runserver - Откройте браузер:
http://127.0.0.1:8000/api/customers/ - В форме внизу страницы введите некорректный номер телефона и нажмите POST
- DRF должен вернуть ошибку валидации с понятным сообщением
Проверка через VS Code
Настройка launch.json для Django
{
"version": "0.2.0",
"configurations": [
{
"name": "Django",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver"],
"django": true,
"justMyCode": true
}
]
}
Отладка сериализатора
- Открыть
store/serializers.py - Поставить точку останова на строку
if not re.match(...вvalidate_phone_number - Запустить сервер через F5 (Debug)
- Отправить POST-запрос через Postman или DRF Browsable API
- VS Code остановится на точке останова — можно проверить значение
value
Проверка через Postman
# POST http://127.0.0.1:8000/api/customers/
# Content-Type: application/json
{
"first_name": "Ivan",
"last_name": "Petrov",
"email": "ivan@example.com",
"phone_number": "abc",
"address": 1
}
# Ожидаемый ответ: 400 Bad Request
# {"phone_number": ["Номер телефона должен содержать от 10 до 15 цифр."]}