Когда фильтров стало несколько и часть «или», запись через цепочки расползалась. Открыл для себя Q — и логика объединилась читаемо. Раньше пугался слова «сложное условие», а оказалось — тот же фильтр, просто собранный логически.
Нейтрально: Q() позволяет строить условия с & (и) и | (или), передавая их одним аргументом в filter.
from django.db.models import Q
# ищем "утро" в имени ИЛИ заметках джуна про утро
results = Habit.objects.filter(
Q(name__icontains="утро") | Q(notes__icontains="утро")
).distinct()
Код стал читаться как вопрос: «найди утро в имени или в заметках». Страх перед «сложными запросами» сменился спокойствием — просто собираю условия через Q. Как и многое в Django, выглядело магией ровно до того, как открыл механику.