1.Django調試工具列
pip install django-debug-toolbar
# settings.py (development only)
INSTALLED_APPS = [..., 'debug_toolbar']
MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware', ...]
INTERNAL_IPS = ['127.0.0.1']
2. 查詢最佳化
# N+1 Problem
# SAI — N+1 queries
products = Product.objects.all()
for p in products:
print(p.category.name) # Mỗi iteration = 1 query
# ĐÚNG — select_related (ForeignKey, OneToOne)
products = Product.objects.select_related('category', 'brand').all()
# ĐÚNG — prefetch_related (ManyToMany, reverse FK)
products = Product.objects.prefetch_related('tags', 'images').all()
# Prefetch với custom queryset
from django.db.models import Prefetch
products = Product.objects.prefetch_related(
Prefetch(
'reviews',
queryset=Review.objects.filter(rating__gte=4).select_related('user'),
to_attr='top_reviews',
)
)
3. 聚合與標註
from django.db.models import Count, Avg, Sum, F, Q
# Thay vì loop tính toán
products = Product.objects.annotate(
review_count=Count('reviews'),
avg_rating=Avg('reviews__rating'),
revenue=F('price') * F('sold_count'),
).filter(
review_count__gte=5,
avg_rating__gte=4.0,
).order_by('-revenue')
# Conditional aggregation
stats = Product.objects.aggregate(
total=Count('id'),
active=Count('id', filter=Q(is_active=True)),
avg_price=Avg('price'),
)
4. 資料庫索引
class Product(models.Model):
name = models.CharField(max_length=255, db_index=True)
slug = models.SlugField(unique=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
indexes = [
models.Index(fields=['category', '-created_at']),
models.Index(fields=['price', 'is_active']),
models.Index(
fields=['name'],
condition=Q(is_active=True),
name='active_product_name_idx',
),
]
5. 連線池和唯讀副本
# pip install django-db-connection-pool
DATABASES = {
'default': {
'ENGINE': 'dj_db_conn_pool.backends.postgresql',
'POOL_OPTIONS': {
'POOL_SIZE': 10,
'MAX_OVERFLOW': 5,
},
},
'replica': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'HOST': 'replica.db.example.com',
},
}
class PrimaryReplicaRouter:
def db_for_read(self, model, **hints):
return 'replica'
def db_for_write(self, model, **hints):
return 'default'
DATABASE_ROUTERS = ['config.routers.PrimaryReplicaRouter']
下一篇: 適用於 Django 的 Docker 和 CI/CD。