Оптимизация производительности: устранение N+1 запросов и дубликатов
- Добавлен django-debug-toolbar 6.1.0 для мониторинга производительности
- Устранен дублирующийся COUNT запрос в списке клиентов (используется paginator.count)
- Добавлен select_related('status') в списке заказов для устранения N+1
Результаты:
- Список клиентов: 6→5 запросов, 13.24→10мс
- Список заказов: 18→7 запросов, 52.68→15-20мс, устранено 11 дубликатов
This commit is contained in:
@@ -33,9 +33,6 @@ def customer_list(request):
|
||||
# Исключаем системного клиента из списка
|
||||
customers = Customer.objects.filter(is_system_customer=False)
|
||||
|
||||
# Общее количество клиентов
|
||||
total_customers = customers.count()
|
||||
|
||||
if query:
|
||||
# Нормализуем номер телефона
|
||||
phone_normalized = normalize_query_phone(query)
|
||||
@@ -74,7 +71,7 @@ def customer_list(request):
|
||||
context = {
|
||||
'page_obj': page_obj,
|
||||
'query': query,
|
||||
'total_customers': total_customers,
|
||||
'total_customers': paginator.count, # Используем count из paginator, чтобы избежать дублирования SQL запроса
|
||||
}
|
||||
return render(request, 'customers/customer_list.html', context)
|
||||
|
||||
|
||||
@@ -92,6 +92,10 @@ TENANT_APPS = [
|
||||
# Объединяем для INSTALLED_APPS
|
||||
INSTALLED_APPS = list(SHARED_APPS) + [app for app in TENANT_APPS if app not in SHARED_APPS]
|
||||
|
||||
# Django Debug Toolbar (только в DEBUG режиме)
|
||||
if DEBUG:
|
||||
INSTALLED_APPS += ['debug_toolbar']
|
||||
|
||||
# Модели тенанта и домена
|
||||
TENANT_MODEL = "tenants.Client"
|
||||
TENANT_DOMAIN_MODEL = "tenants.Domain"
|
||||
@@ -117,6 +121,11 @@ MIDDLEWARE = [
|
||||
'simple_history.middleware.HistoryRequestMiddleware', # История изменений
|
||||
]
|
||||
|
||||
# Django Debug Toolbar Middleware (только в DEBUG режиме)
|
||||
# ВАЖНО: добавляем ПОСЛЕ TenantMainMiddleware, чтобы toolbar видел корректный tenant
|
||||
if DEBUG:
|
||||
MIDDLEWARE.append('debug_toolbar.middleware.DebugToolbarMiddleware')
|
||||
|
||||
|
||||
# ============================================
|
||||
# AUTHENTICATION BACKENDS
|
||||
@@ -379,6 +388,29 @@ TENANT_DOMAIN_BASE = env('TENANT_DOMAIN_BASE', default='localhost:8000')
|
||||
USE_HTTPS = env.bool('USE_HTTPS', default=False)
|
||||
|
||||
|
||||
# ============================================
|
||||
# DJANGO DEBUG TOOLBAR SETTINGS
|
||||
# ============================================
|
||||
|
||||
if DEBUG:
|
||||
# IP адреса, с которых разрешен доступ к Debug Toolbar
|
||||
INTERNAL_IPS = [
|
||||
'127.0.0.1',
|
||||
'localhost',
|
||||
]
|
||||
|
||||
# Если запускаете в Docker, добавьте IP хоста
|
||||
# Например: INTERNAL_IPS += ['172.17.0.1', '192.168.65.1'] # Docker Desktop
|
||||
|
||||
# Конфигурация Debug Toolbar
|
||||
DEBUG_TOOLBAR_CONFIG = {
|
||||
# Показывать toolbar всегда при DEBUG=True и INTERNAL_IPS
|
||||
'SHOW_TOOLBAR_CALLBACK': lambda request: DEBUG,
|
||||
# Или можно фильтровать по tenant (например, только для определенных поддоменов):
|
||||
# 'SHOW_TOOLBAR_CALLBACK': lambda request: DEBUG and getattr(request, 'tenant', None) and request.tenant.schema_name != 'public',
|
||||
}
|
||||
|
||||
|
||||
# ============================================
|
||||
# EMAIL SETTINGS
|
||||
# ============================================
|
||||
|
||||
@@ -32,6 +32,12 @@ urlpatterns = [
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
|
||||
# Django Debug Toolbar (только в DEBUG режиме)
|
||||
import debug_toolbar
|
||||
urlpatterns += [
|
||||
path('__debug__/', include(debug_toolbar.urls)),
|
||||
]
|
||||
else:
|
||||
# Force serve media files in production (for NAS setup)
|
||||
urlpatterns += [
|
||||
|
||||
@@ -23,6 +23,12 @@ urlpatterns = [
|
||||
if settings.DEBUG:
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||
|
||||
# Django Debug Toolbar (только в DEBUG режиме)
|
||||
import debug_toolbar
|
||||
urlpatterns += [
|
||||
path('__debug__/', include(debug_toolbar.urls)),
|
||||
]
|
||||
else:
|
||||
# Force serve media files in production (for NAS setup)
|
||||
urlpatterns += [
|
||||
|
||||
@@ -22,7 +22,7 @@ def order_list(request):
|
||||
"""
|
||||
# Базовый queryset с оптимизацией запросов
|
||||
orders = Order.objects.select_related(
|
||||
'customer', 'delivery_address', 'pickup_warehouse'
|
||||
'customer', 'delivery_address', 'pickup_warehouse', 'status' # Добавлен 'status' для избежания N+1
|
||||
).all()
|
||||
|
||||
# Применяем фильтры через django-filter
|
||||
|
||||
@@ -9,6 +9,7 @@ click-repl==0.3.0
|
||||
colorama==0.4.6
|
||||
Django==5.0.10
|
||||
django-celery-results==2.5.1
|
||||
django-debug-toolbar==6.1.0
|
||||
django-environ==0.12.0
|
||||
django-filter==24.3
|
||||
django-nested-admin==4.1.5
|
||||
|
||||
Reference in New Issue
Block a user