🏠 Практика: закрепление сериализаторов DRF

Информация: Это не LMS-домашнее задание. Это закрепляющее задание для самостоятельной практики по теме урока. Выполняется локально, проверяется через DRF Browsable API и Postman.

⚡ Задача для самостоятельной практики

Расширить сериализаторы store-приложения:

  1. Добавить validate_email в CustomerCreateUpdateSerializer — проверить формат email через regex
  2. Создать ProductListSerializer — только поля id, name, price для списка
  3. Добавить кросс-полевую валидацию в 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

  1. Запустите сервер: python manage.py runserver
  2. Откройте браузер: http://127.0.0.1:8000/api/customers/
  3. В форме внизу страницы введите некорректный номер телефона и нажмите POST
  4. 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
        }
    ]
}

Отладка сериализатора

  1. Открыть store/serializers.py
  2. Поставить точку останова на строку if not re.match(... в validate_phone_number
  3. Запустить сервер через F5 (Debug)
  4. Отправить POST-запрос через Postman или DRF Browsable API
  5. 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 цифр."]}

Связь с теорией

← К оглавлению урока    ← Ресурсы