У попередньому уроці ми розглянули тему юніт-тестування. У цьому уроці я поясню, як встановити PostgreSQL на Ubuntu, використовуючи статтю від DigitalOcean. Після цього ми інтегруємо PostgreSQL у наш Django проєкт.
Розпочнемо з встановлення PostgreSQL за допомогою цієї документації. Це найкраще керівництво для встановлення PostgreSQL. Створіть нову базу даних “pawnshop” і використовуйте postgres:postgres для імені користувача та пароля.
Далі відкрийте проєкт і знайдіть цей розділ у settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
Змініть його на цю конфігурацію
DATABASES = {
"default": {
"ENGINE": os.environ.get("POSTGRES_ENGINE"),
"NAME": os.environ.get("POSTGRES_DB"),
"USER": os.environ.get("POSTGRES_USER"),
"PASSWORD": os.environ.get("POSTGRES_PASSWORD"),
"HOST": os.environ.get("POSTGRES_HOST", "0.0.0.0"),
"PORT": os.environ.get("POSTGRES_PORT"),
"OPTIONS": {"options": "-c search_path=public"},
}
}
Додайте нові змінні в файл .env
....
POSTGRES_ENGINE=django.db.backends.postgresql
POSTGRES_DB=pawnshop
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
Потім
python manage.py makemigrations # Не обов'язково
python manage.py migrate
kill -9 $(lsof -t -i:8000) || echo "Port has already cleared" && python manage.py runserver 8000
Все готово! Тепер ви можете використовувати такі інструменти, як DBeaver (безкоштовний), для управління базами даних. Наступна тема — сигнали. Після створення продукту ми хочемо надіслати електронного листа адміністратору. Для цього ми використовуємо сигнали Django.
Що таке сигнали Django?
Сигнали Django — це спосіб дозволити декупльованим додаткам взаємодіяти між собою. Вони використовуються для виконання певних дій, коли в рамках фреймворка відбуваються специфічні події, наприклад, коли модель зберігається або видаляється. Сигнали дозволяють розробникам виконувати власну логіку у відповідь на ці події, не змінюючи основну функціональність.
Зазвичай використовувані сигнали
- postsave_:
Цей сигнал спрацьовує після того, як екземпляр моделі збережено (створено або оновлено). Він дозволяє виконати дії після збереження даних у базі даних. Наприклад, можна надіслати електронний лист, оновити пов'язані моделі або зафіксувати подію. - presave_:
Цей сигнал спрацьовує безпосередньо перед тим, як екземпляр моделі буде збережено в базі даних.
Часто використовується для валідації даних, модифікації або будь-яких перевірок перед збереженням.
Ключові параметри в сигналах
- sender: Модель, яка надсилає сигнал.
- instance: Екземпляр моделі, який ініціює сигнал.
- created: Булеве значення, яке вказує, чи є екземпляр новим (True) або оновленим (False).
Приклад:
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from myapp.models import Product
from django.core.mail import send_mail
# Приклад: pre_save Сигнал
@receiver(pre_save, sender=Product)
def before_saving_product(sender, instance, **kwargs):
print(f"Готуємось зберегти продукт: {instance.name}")
# Приклад: post_save Сигнал
@receiver(post_save, sender=Product)
def after_saving_product(sender, instance, created, **kwargs):
if created:
# Дія для новоствореного продукту
send_mail(
'Новий продукт додано',
f'Продукт "{instance.name}" успішно додано.',
'[email protected]',
['[email protected]'],
)
print(f"Продукт {instance.name} збережено, і електронний лист надіслано!")
else:
print(f"Продукт {instance.name} оновлено.")
Коли використовувати сигнали?
- postsave_: Для задач, таких як надсилання підтверджувальних електронних листів, оновлення кешу або активація сповіщень після збереження даних.
- presave_: Для задач, таких як модифікація даних перед збереженням, забезпечення цілісності або журналювання незбережених змін.
Сигнали Django — потужний інструмент, але їх слід використовувати обережно, щоб уникнути занадто тісної прив'язки компонентів або створення складного для налагодження коду.
Створімо новий файл.
sudo touch products/signals.py
sudo chown -R $(whoami) products/*
Остаточна структура:
pawnshop/
├── .env
├── manage.py
├── conftest.py
├── pytest.ini
├── pawnshop/
│ ├── __init__.py
│ ├── views.py
│ ├── serializers.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
├── products/
├── tests/
│ ├── test_models.py
│ ├── test_views.py
├── migrations/
│ ├── __init__.py
├── __init__.py
├── admin.py
├── signals.py # Новий
├── apps.py
├── models.py
├── serializers.py
├── tests.py
├── urls.py
├── views.py
signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.mail import send_mail
from .models import Product
@receiver(post_save, sender=Product)
def send_product_email(sender, instance, created, **kwargs):
if created:
subject = "Новий продукт додано"
message = f"Новий продукт додано:\n\nНазва: {instance.name}\nОпис: {instance.description}\nЦіна: ${instance.price}"
from_email = "[email protected]"
recipient_list = ["[email protected]"]
# Надсилання пошти
send_mail(subject, message, from_email, recipient_list)
І імпортуємо сигнали до Apps
products/apps.py
from django.apps import AppConfig
class ProductsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'products'
def ready(self): # Новий
import products.signals
Додайте smtp-дані до файлу .env.
Остаточна версія .env
API_TITLE=Pawnshop
API_DESCRIPTION=Продукти ломбарду
API_VERSION=v0.0.0
SERVE_PUBLIC=PawnshopTest
POSTGRES_ENGINE=django.db.backends.postgresql
POSTGRES_DB=aractakasi
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
DATABASE=aractakasi
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'your_email_password'
Використовуйте свої облікові дані електронної пошти в файлі .env, змініть EMAILHOSTUSER та EMAILHOSTPASSWORD. І отримуйте ці дані з змінних середовища в settings.py
settings.py
...
EMAIL_BACKEND = os.environ.get("EMAIL_BACKEND")
EMAIL_HOST = os.environ.get("EMAIL_HOST")
EMAIL_PORT = os.environ.get("EMAIL_PORT")
EMAIL_USE_TLS = os.environ.get("EMAIL_USE_TLS")
EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_HOST_PASSWORD")
Отже, якщо ви створите новий продукт у Postman, сигнал postsave_ (post_save) буде спрацьовувати.
Ми дійшли до кінця цього уроку. У наступному уроці ми розглянемо аутентифікацію JWT для нашого Django проєкту.
Ви можете знайти вихідний код ТУТ.
Перекладено з: DRF Part 4: Mastering Django Rest Framework: Integrate PostgreSQL Database and Django Signals