Django условно фильтрующие объекты
Я хотел бы получить кучу строк из моей базы данных с помощью набора фильтров.
Мне было интересно, применим ли условный фильтр в django. То есть, "фильтр, если переменная не является None, или не применяет фильтрацию в противном случае".
Что-то вроде этого:
user = User.objects.get(pk=1)
category = Category.objects.get(pk=1)
todays_items = Item.objects.filter(user=user, date=now()).conditional_filter(category=category))
Что бы я хотел сделать, это применить фильтр категории только в том случае, если категория не является None.
Если категория равна None (означает, что она не указана в объекте запроса), этот фильтр вообще не будет применяться. Это избавит меня от кучи ситуаций "if-elif-else".
Есть ли способ сделать это?
Ответы
Ответ 1
Вы можете связать запросы:
user = User.objects.get(pk=1)
category = Category.objects.get(pk=1)
qs = Item.objects.filter(user=user, date=now())
if category:
qs = qs.filter(category=category)
Так как запрос выполняется лениво, результат БД происходит только при отображении элементов.
Ответ 2
Ну, это довольно старый вопрос, но для тех, кто хотел бы выполнить условную фильтрацию на одной строке, вот мой подход (Btw, следующий код, вероятно, может быть написан более общим образом):
from django.db.models import Q
def conditional_category_filter(category):
if category != None:
return Q(category=category)
else:
return Q() #Dummy filter
user = User.objects.get(pk=1)
category = Category.objects.get(pk=1)
todays_items = Item.objects.filter(conditional_category_filter(category), user=user, date=now())
Единственное, что вам нужно посмотреть, это использовать вызов conditional_category_filter(category)
перед аргументами ключевого слова, например user=user
. Например, следующий код вызовет ошибку:
todays_items = Item.objects.filter(user=user, date=now(), conditional_category_filter(category))
Ответ 3
Это несколько подходов к вашей проблеме. Один из подходов - играть с Комплексный поиск с объектами Q
from django.db.models import Q
user = User.objects.get(pk=1)
category = Category.objects.get(pk=1)
f1 = Q( user=user, date=now() )
f_cat_is_none = Q( category__isnull = True )
f_cat_is_not_none = Q( category=category )
todays_items = Item.objects.filter( f1 & ( f_cat_is_none | f_cat_is_not_none ) )
Я не понимаю в вашем ответе, если это запрос, который вы ищете, но в этом примере вы можете легко составить свой собственный запрос.
Отредактированный комментарий OP
category__isnull == True
означает, что в базе данных элемент не связан с категорией.
Возможно, запрос, который вы ищете, это:
from django.db.models import Q
user_pk = 1
category_pk = 1 #some times None
f = Q( user__pk = user_pk, date=now() )
if category_pk is not None:
f &= Q( category__pk = category_pk )
todays_items = Item.objects.filter( f )
Это всего лишь образец кода, соответствующий его требованиям. Будьте осторожны с одиночными _
и двойными __
.