Подтвердить что ты не робот

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".

Есть ли способ сделать это?

4b9b3361

Ответ 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  )

Это всего лишь образец кода, соответствующий его требованиям. Будьте осторожны с одиночными _ и двойными __.