F() tham chiếu giá trị cột ngay ở DB-side để cập nhật mà không cần đọc về Python — nhờ vậy tránh được race condition khi nhiều request cùng tăng cùng một cột.
python
from django.db.models import F
# Sai: race nếu 2 request chạy song song
product.views = product.views + 1
product.save()
# Đúng: Django sinh UPDATE ... SET views = views + 1
Product.objects.filter(id=pid).update(views=F('views') + 1)Q() đóng gói điều kiện thành object để combine bằng | (OR), & (AND), ~ (NOT) — .filter(...) mặc định chỉ AND, không gộp OR được.
python
from django.db.models import Q
Post.objects.filter(
Q(title__icontains='django') | Q(tags__name='django'),
published=True,
)Hai thứ dễ vấp khi dùng: sau khi F() update, instance Python vẫn còn giữ giá trị cũ — muốn đọc giá trị mới phải refresh_from_db().
Còn Q() lồng nhiều OR trên bảng lớn mà không có index thì Postgres planner sẽ chuyển sang seq scan, search chậm như rùa — cân nhắc index GIN/trigram cho search.