Ось твій урок. Вмикай уяву — ми в лекційній залі, на екрані код, а я ходжу сценою і пояснюю, чому твій Django-проєкт має змінитися.
🎓 CS50: Архітектура Production-проєкту на Django
Привіт, друзі! 👋
1. 🔥 Вступ: Хаос у гуртожитку vs Порядок на фабриці
Уявіть ситуацію. Ви пишете свій перший Django-проєкт. Це як жити в студентському гуртожитку: в одній кімнаті ви спите, їсте, сушите одяг і вчитеся. Все під рукою. Файл settings.py — це ваш стіл: тут лежить паспорт (паролі), недоїдена піца (статичні файли) і підручники (налаштування БД).
І це працює. Поки ви одні.
Але уявіть, що завтра ваш стартап «вистрілив». До вас прийшли 100 000 користувачів. Ви наймаєте ще 5 розробників. Ви намагаєтесь розгорнути цей проєкт на сервері, і... БУМ! 💥
- Ви випадково залили
DEBUG=Trueна продакшн, і хакери бачать ваші помилки. - Ваш пароль від бази даних потрапив у GitHub, бо він був зашитий прямо в коді.
- Колега змінив налаштування для тестування, і це зламало роботу всього сайту.
Риторичне питання: Ви б довірили свої гроші банку, який тримає ключі від сейфа під килимком біля входу? Точно ні.
Чому без цього не обійтись?
Стандартна структура django-admin startproject — це лише заготовка. Для Production (реального життя) нам потрібна архітектура, яка:
1. Безпечна (секрети окремо від коду).
2. Гнучка (різні налаштування для локальної розробки та сервера).
3. Масштабована (код структурований, а не звалений в купу).
Сьогодні ми перетворимо ваш "гуртожиток" на професійний "хмарочос". 🏢
2. 🧠 Теоретична база: Як це працює «під капотом»
Перш ніж писати код, зрозуміємо філософію. Є один принцип, який ви маєте викарбувати у пам'яті: The Twelve-Factor App (Додаток 12 факторів).
Ми зосередимось на двох головних факторах.
1. Конфігурація (Config)
Код залишається незмінним, де б він не запускався (на вашому ноутбуці чи на сервері Amazon). Змінюватися має лише конфігурація. * Локально: БД — SQLite, дебаг — увімкнено. * Production: БД — PostgreSQL, дебаг — вимкнено, пошта — реальний SMTP.
Як це реалізувати?
Замість одного settings.py, ми розділимо налаштування. А секретні дані (паролі, API-ключі) винесемо у змінні оточення (Environment Variables). Це як «привиди» операційної системи — програма їх бачить, але у файлах коду їх немає.
2. Структура застосунків (Apps)
За замовчуванням Django кидає всі ваші app (blog, users, shop) в корінь проєкту. Коли їх стає 10, корінь перетворюється на смітник.
Ми навчимося ховати їх у папку apps/.
3. 🧪 Приклади: Від простого до PRO
Етап 1: Розрізаємо settings.py
Що ви очікуєте побачити у папці з налаштуваннями великого проєкту? Один файл на 500 рядків? Ні.
❌ Як було:
myproject/
settings.py <-- Тут все в купі
✅ Як має бути:
Ми видаляємо settings.py і створюємо папку settings/:
myproject/
settings/
__init__.py
base.py <-- Спільні налаштування (INSTALLED_APPS, Middleware)
local.py <-- Для розробки (DEBUG=True, SQLite)
prod.py <-- Для сервера (DEBUG=False, Sentry, AWS S3)
У чому магія?
У файлі local.py ми пишемо:
from .base import * # Імпортуємо все зі спільного файлу
DEBUG = True
DATABASES = { ... } # Локальна база
Тепер ви можете запускати сервер так:
python manage.py runserver --settings=myproject.settings.local
Етап 2: Змінні оточення (Environment Variables)
Уявіть, що SECRET_KEY — це пін-код від вашої картки. Ви ж не пишете його на картці маркером?
❌ Погано (Hardcoded):
# settings/prod.py
SECRET_KEY = 'super-secret-password-123' # 😱 Це побачать всі на GitHub!
✅ Професійно (.env):
Ми використовуємо бібліотеку (наприклад, python-decouple або django-environ).
Створюємо файл .env (який додаємо в .gitignore!):
SECRET_KEY=j#8s9d8s9d8...
DB_PASSWORD=my_strong_password
DEBUG=False
А в коді читаємо це так:
# settings/base.py
from decouple import config
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
Чому це круто? Якщо ви зміните пароль від бази, вам не треба переписувати код і робити новий git commit. Ви просто змінюєте рядок у .env на сервері. Перезапуск — і все працює.
Етап 3: Чистий корінь (Apps folder)
Коли у вас 15 додатків, корінь проєкту виглядає жахливо. Давайте приберемось.
Структура:
myproject/
apps/ <-- Створюємо папку
users/
blog/
payment/
manage.py
Але Django не побачить ці додатки просто так. Нам треба підказати йому шлях.
У settings/base.py:
import sys
import os
# Додаємо папку apps у системний шлях пошуку
PROJECT_ROOT = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(PROJECT_ROOT, '../apps'))
INSTALLED_APPS = [
...
'apps.users', # Або просто 'users', якщо sys.path налаштовано
'apps.blog',
]
4. 🛠 Практична частина
Час забруднити руки! Виконай ці завдання, щоб відчути різницю.
Завдання 1: Операція "Розчленування" 🪚
1. Створи новий Django-проєкт.
2. Перетвори файл settings.py на пакет (папку) settings/.
3. Розділи налаштування на base.py та local.py.
4. Запусти проєкт, явно вказавши --settings=....
Завдання 2: Секретна кімната 🕵️♂️
1. Встанови python-decouple.
2. Створи файл .env і перенесіть туди SECRET_KEY.
3. Зроби так, щоб при відсутності .env проєкту видавав помилку (це важливо для безпеки!).
Завдання 3: "А що, якщо..." 🤔
Зміни .env файл: постав DEBUG=False. Спробуй зайти на неіснуючу сторінку (404).
Що змінилося у відображенні помилки? Чому це критично для продакшну?
Завдання 4: Міні-кейс 💼
Ти розробляєш інтернет-магазин.
* Локально ти хочеш, щоб листи (підтвердження замовлення) друкувалися просто в консоль (Console Backend).
* На проді вони мають йти через реальний SMTP (Gmail або SendGrid).
* Напиши умову в settings, як це реалізувати, не змінюючи код при деплої.
5. 💡 Мислення як у розробника
Ось де новачки спотикаються, а профі — посміхаються.
Типова помилка: "Fat Views" (Товсті в'юшки)
Новачки пхають всю бізнес-логіку у views.py.
* "Якщо користувач купив товар, перевір залишок, спиши гроші, відправ лист, онови статистику..." — і все це у функції buy_item.
Як думає профі:
Views мають бути тупими. Вони лише приймають запит і віддають відповідь.
Усю логіку ми виносимо у services.py або selectors.py.
* services.create_order(user, item) — ось і вся логіка у View.
Порада: 12-факторний рефлекс
Кожного разу, коли ти хочеш написати конкретний шлях до файлу (C:/Users/David/project...) або конкретний пароль у коді — бий себе по руках 👋. Винось це у конфігурацію.
Порада: Docker
Ця архітектура, яку ми сьогодні розібрали, ідеально лягає в Docker. Якщо ти розділив settings і використовуєш .env, загорнути проєкт у контейнер займе 5 хвилин. Якщо ні — це буде пекло.
6. 🧩 Підсумок
Отже, що ми сьогодні зробили?
1. Ми прибрали хаос, розділивши налаштування (base, local, prod).
2. Ми захистили секрети, використовуючи змінні оточення (.env).
3. Ми підготували ґрунт для масштабування, сховавши додатки в apps/.
Тепер твій проєкт виглядає не як студентська лабораторна, а як серйозний продукт, готовий до мільйонів запитів.
🔍 Тизер наступного уроку: Тепер, коли у нас така класна архітектура, як нам змусити це все працювати швидко під навантаженням? Наступного разу ми поговоримо про Кешування (Redis) та асинхронність (Celery). Чому Django іноді треба "відкласти справи на потім"?
А на сьогодні це все. Це був CS50. Щасти! 🚀