django有条件地过滤物体

xpa*_*nta 23 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))
Run Code Online (Sandbox Code Playgroud)

我想要做的是仅在类别不是None时应用类别过滤器.

如果category为None(表示未在请求对象中给出),则根本不应用此过滤器.这样可以省去一堆'if-elif-else'的情况.

有没有办法做到这一点?

bmi*_*lac 26

您可以链接查询:

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)
Run Code Online (Sandbox Code Playgroud)

由于查询集是懒惰地执行的,因此只有在显示项目时才会发生数据库命中.


dan*_*era 12

它们是解决您问题的几种方法.一种方法是使用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 ) )
Run Code Online (Sandbox Code Playgroud)

如果这是您要查找的查询,我在您的答案中无法理解,但是,通过此示例,您可以轻松地编写自己的查询.

编辑到期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  )
Run Code Online (Sandbox Code Playgroud)

这只是一个代码示例,符合您的要求.小心_单双 __.


iuy*_*sal 5

嗯,这是一个相当古老的问题,但对于那些想要在一行上进行条件过滤的人来说,这是我的方法(顺便说一句,以下代码可能以更通用的方式编写):

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())
Run Code Online (Sandbox Code Playgroud)

您需要注意的唯一事情是conditional_category_filter(category)在关键字参数之前使用调用user=user.例如,以下代码将引发错误:

todays_items = Item.objects.filter(user=user, date=now(), conditional_category_filter(category))
Run Code Online (Sandbox Code Playgroud)