django条件筛选对象

django条件筛选对象,django,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)) 我想做的是

我想使用一组过滤器从数据库中检索一组行

我想知道条件过滤器是否适用于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))
我想做的是仅当类别不是“无”时应用类别过滤器

如果category为None(表示请求对象中没有给出),则根本不会应用此筛选器。这会帮我省下一大堆“如果elif else”的情况


有什么方法可以做到这一点吗?

它们是解决您的问题的几种方法。一种方法是玩游戏

我不太明白您的答案中是否有您正在寻找的查询,但是,通过这个示例,您可以轻松编写自己的查询

已编辑到期评论

category\uu 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  )
这只是一个代码示例,适合您的需求。小心使用单
\uu
和双
\u

您可以链接查询:

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)

由于queryset是延迟执行的,只有在显示项目时才会出现DB hit。

好吧,这是一个很老的问题,但对于那些想在一行上执行条件筛选的人来说,我的方法是(顺便说一句,以下代码可能可以用更通用的方式编写):

唯一需要注意的是在关键字参数之前使用
user=user
调用
conditional\u category\u过滤器(category)
。例如,以下代码将引发错误:

todays_items = Item.objects.filter(user=user, date=now(), conditional_category_filter(category))

要继续@iuysal应答,请执行以下操作:

要使其通用,您还需要将密钥作为参数传递,要做到这一点,您需要传递字典,我是这样做的:

按如下方式创建词典:

filters={'filter1':'value1','filter2_uustartswith':'valu',…}
然后将其传递到您的项目筛选器,如下所示:

Item.objects.filter(*[Q(**{k:v})表示k,v在filters.items()中表示v,filter3='value3')
我的第一个版本不那么神秘:

def_过滤器(过滤器):
过滤器=[]
对于n.项()中的k,v:
如果v:
filters.append(Q(**{k:v}))
返回过滤器
筛选器=_筛选器({'name':name})
返回项.objects.filter(*filters)
解包说明:我们希望将
Q(查询)
作为
args
提供给
对象。筛选
作为args,同时我们希望将
kwargs
提供给
Q()

我现在已经开始生产了(我将修改过滤器名称,因为它很敏感):

def get_queryset(self):
filter1=self.request.GET.GET('filter1','')
filter2\u startswith=self.request.GET.GET('filter2\u前缀','')
def过滤器到过滤器(过滤器):
在filters.items()中为k返回[Q(**{k:v}),如果v]
过滤器={'filter1':过滤器1,
“filter2\uuuu startswith”:filter2\uuuu startswith}
退货订单.objects.filter(*filters_to_Qs(filters))
qs
中,我们将获得过滤结果
谢谢,我不明白的是
category\uu isnull=True
。我的所有对象在其类别字段中都没有空值。这使得它总是错误的。@xpanta,在回答中解释。@danihp,对不起,我仍然不太理解uu isnull=True。它是否适用于这种情况:包含“类别”的表单,用户填写并提交表单。如果用户未输入“类别”,则此值为“”。那么,如果我遵循您的第一个示例,是否可以在不受“category”约束的情况下过滤数据库?如果我的理解正确,请纠正我。提前谢谢。@Elena,对不起,不知道你要什么<代码>\uuu isnull
在第一个示例中表示没有类别的项目。最令人满意的简单答案这是一个可读且易于实现的答案,而且由于查询集是惰性评估的,因此性能良好。
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())
todays_items = Item.objects.filter(user=user, date=now(), conditional_category_filter(category))
from django.db.models import Q

qs = Users.objects.filter(
                    p_id=parent_id,
                    status=True
                ).all()

if user_id>0:
    qs = qs.filter( ~Q(id=user_id) )