🏠 Закрепляющая практика: Урок 27
Замечание: Для урока 27 (практикум) официального LMS-домашнего задания нет — оно совпадает с задачами урока. Данная страница содержит закрепляющее самостоятельное задание сверх практикума.
⚡ Кратко: что нужно сделать
Написать скрипт store_analysis.py в Django shell, который выводит аналитику по магазину: топ-5 категорий по выручке, топ-3 клиента по тратам, заказы за последние 7 дней, продукты с коротким сроком годности (менее 30 дней).
# Запуск
python manage.py shell
exec(open('store_analysis.py').read())
Задание
Напишите скрипт store_analysis.py, который при запуске через Django shell выводит аналитический отчёт по магазину. Используйте только изученные инструменты: aggregate(), annotate(), order_by(), timezone и срезы.
Что должен делать скрипт
-
Топ-5 категорий по выручке
Выручка = сумма (цена × количество) по всем продуктам в категории.
Вывод: название категории и общая выручка, отсортированные по убыванию. -
Топ-3 клиента по сумме заказов
ИспользуйтеOrder→OrderItem→ клиент.
Вывод: имя, фамилия, общая сумма заказов. -
Заказы за последние 7 дней
Используйтеtimezone.now() - timezone.timedelta(days=7).
Вывод: ID заказа и дата. -
Продукты с коротким сроком годности (менее 30 дней)
Вычислите разницуexpiration_date - manufacturing_dateчерезExpressionWrapper.
Отфильтруйте продукты сlifetime.days < 30.
Вывод: название продукта и срок жизни в днях.
Подготовка окружения
# 1. Создать и активировать виртуальное окружение
python -m venv venv
# Windows PowerShell:
.\venv\Scripts\Activate.ps1
# 2. Установить зависимости
pip install django
# 3. Убедиться, что проект настроен
python manage.py check
# 4. Загрузить тестовые данные (если ещё не загружены)
python manage.py shell
from store_data import *
export_data()
exit()
Решение
store_analysis.py
# store_analysis.py — аналитика по магазину (запускать через Django shell)
from django.db.models import Sum, F, Count, Avg, ExpressionWrapper, fields
from django.utils import timezone
from store.models import Product, Order, OrderItem, ProductDetail
print("=" * 50)
print("АНАЛИТИКА МАГАЗИНА")
print("=" * 50)
# 1. Топ-5 категорий по выручке
print("\n1. Топ-5 категорий по выручке:")
top_categories = Product.objects.values('category__name').annotate(
revenue=Sum(F('price') * F('quantity'))
).order_by('-revenue')[:5]
for i, cat in enumerate(top_categories, 1):
print(f" {i}. {cat['category__name']}: {cat['revenue']}")
# 2. Топ-3 клиента по сумме заказов
print("\n2. Топ-3 клиента по сумме заказов:")
top_customers = Order.objects.values(
'customer__first_name',
'customer__last_name'
).annotate(
total_spent=Sum(F('order_items__price') * F('order_items__quantity'))
).order_by('-total_spent')[:3]
for i, cust in enumerate(top_customers, 1):
print(
f" {i}. {cust['customer__first_name']} {cust['customer__last_name']}: "
f"{cust['total_spent']}"
)
# 3. Заказы за последние 7 дней
print("\n3. Заказы за последние 7 дней:")
week_ago = timezone.now() - timezone.timedelta(days=7)
recent_orders = Order.objects.filter(order_date__gte=week_ago)
if recent_orders.exists():
for order in recent_orders:
print(f" Заказ #{order.id}, дата: {order.order_date.date()}")
else:
print(" Нет заказов за последние 7 дней")
# 4. Продукты с коротким сроком годности (менее 30 дней)
print("\n4. Продукты с коротким сроком годности:")
short_lifetime = ProductDetail.objects.annotate(
lifetime=ExpressionWrapper(
F('expiration_date') - F('manufacturing_date'),
output_field=fields.DurationField()
)
).filter(lifetime__lt=timezone.timedelta(days=30)).select_related('product')
if short_lifetime.exists():
for detail in short_lifetime:
print(f" {detail.product.name}: {detail.lifetime.days} дней")
else:
print(" Нет продуктов с коротким сроком годности")
print("\n" + "=" * 50)
Как запустить скрипт
# Вариант 1: через shell
python manage.py shell
exec(open('store_analysis.py').read())
# Вариант 2: передать как скрипт напрямую
python manage.py shell < store_analysis.py
Проверка в VS Code
Настройка терминала
- Открыть встроенный терминал: Ctrl + `
- Активировать venv:
.\venv\Scripts\Activate.ps1 - Запустить:
python manage.py shell - Выполнить:
exec(open('store_analysis.py').read())
Настройка launch.json для отладки (F5)
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Django Shell",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["shell"],
"django": true,
"justMyCode": true
}
]
}
Точки останова
- Откройте
store_analysis.pyв VS Code - Кликните левее номера строки, чтобы поставить точку останова (красная точка)
- Нажмите F5 для запуска в режиме отладки
- В панели Variables проверьте содержимое QuerySet
Критерии выполнения
- Скрипт запускается без ошибок
- Все 4 блока вывода присутствуют
- Использован
timezone.now(), а неdatetime.now() - ExpressionWrapper содержит
output_field=fields.DurationField() - Срезы применены на уровне QuerySet (
[:5],[:3]), а не послеlist()