Налаштування Django ORM для Python веб-застосунку

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування Django ORM для Python веб-застосунку
Середня
~1 робочий день
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Настройка Django ORM для Python веб-застосунку

Django ORM вбудована у фреймворк і не потребує окремої встановлення, але правильна конфігурація суттєво впливає на продуктивність та масштабованість. Розглядаємо Django 4.2+ з PostgreSQL.

Підключення до бази даних

У settings.py визначаємо кілька баз при необхідності:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': env('DB_NAME'),
        'USER': env('DB_USER'),
        'PASSWORD': env('DB_PASSWORD'),
        'HOST': env('DB_HOST', default='127.0.0.1'),
        'PORT': env('DB_PORT', default='5432'),
        'CONN_MAX_AGE': 60,
        'OPTIONS': {
            'connect_timeout': 10,
            'options': '-c search_path=public',
        },
    },
}

CONN_MAX_AGE включає persistent connections — Django не буде закривати з'єднання з БД після кожного HTTP-запиту, що зменшує latency. Стандартна практика для gunicorn з кількома воркерами.

Моделі

# catalog/models.py
from django.db import models

class Product(models.Model):
    title = models.CharField(max_length=500)
    slug = models.SlugField(unique=True, max_length=520)
    category = models.ForeignKey(
        'Category',
        on_delete=models.PROTECT,
        related_name='products',
    )
    price = models.DecimalField(max_digits=12, decimal_places=2)
    status = models.CharField(
        max_length=10,
        choices=[('draft', 'Draft'), ('published', 'Published')],
        default='draft',
    )
    tags = models.ManyToManyField('Tag', blank=True, related_name='products')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        indexes = [
            models.Index(fields=['status', '-created_at']),
            models.Index(fields=['category', 'status']),
        ]

Кастомні менеджери та QuerySet

class PublishedProductQuerySet(models.QuerySet):
    def published(self):
        return self.filter(status='published')

    def with_category(self):
        return self.select_related('category')

    def with_tags(self):
        return self.prefetch_related('tags')

class ProductManager(models.Manager):
    def get_queryset(self):
        return PublishedProductQuerySet(self.model, using=self._db)

    def published(self):
        return self.get_queryset().published()

# У моделі:
# objects = ProductManager()

Анотації та агрегації

from django.db.models import Count, Avg, F, Q

stats = (
    Category.objects
    .annotate(
        product_count=Count('products', filter=Q(products__status='published')),
        avg_price=Avg('products__price', filter=Q(products__status='published')),
    )
    .filter(product_count__gt=0)
    .order_by('-product_count')
)

Міграції на production

Кілька правил, які гарантують відсутність простоїв:

  • Додавання nullable-колонки не блокує таблицю в PostgreSQL 11+
  • Додавання індексу — тільки CONCURRENTLY: AddIndex використовує його автоматично для PostgreSQL
  • Переймену вання колонки — завжди у два етапи: добавити нову → скопіювати дані → видалити старку
  • --fake міграція потрібна тільки для синхронізації стану без переповторного застосування SQL
python manage.py migrate --plan
python manage.py migrate
python manage.py showmigrations

Терміни

Первісна настройка нового Django-проекту з моделями, міграціями, роутером на реплику, базовими менеджерами: 1 день. Рефакторинг існуючого проекту для усунення N+1 запитів, додавання індексів: 1–2 дні.