我想使用一组过滤器从我的数据库中检索一堆行.
我想知道条件过滤器是否适用于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)
这只是一个代码示例,符合您的要求.小心_单双 __.
嗯,这是一个相当古老的问题,但对于那些想要在一行上进行条件过滤的人来说,这是我的方法(顺便说一句,以下代码可能以更通用的方式编写):
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)