Django.filter在同一选项上具有多种可能性

Django.filter在同一选项上具有多种可能性,django,filter,Django,Filter,我有一个物体模型。我还有一个过滤结果的选项列表。我不确定是否有一种简单的方法可以过滤模型中的对象,从而返回与过滤器列表中的任何项匹配的任何对象。例如: # returns all users with name starting with 'P' usersWithPName = User.objects.filter(name__startswith = 'P') # 3 letters to filter User model with filterList = ['P', 'T', 'R'

我有一个物体模型。我还有一个过滤结果的选项列表。我不确定是否有一种简单的方法可以过滤模型中的对象,从而返回与过滤器列表中的任何项匹配的任何对象。例如:

# returns all users with name starting with 'P'
usersWithPName = User.objects.filter(name__startswith = 'P')
# 3 letters to filter User model with
filterList = ['P', 'T', 'R'] 
# ideally would return all users with name starting with either 'P', 'T', or 'R'
usersWithPTRName = User.objects.filter(name__startswith = filterList) 
是否有任何方法可以过滤(在本例中)用户模型,从而返回与filterList中任何一项匹配的任何对象?

两个选择

  • 将第一个字母作为属性包含在模型中

  • 使用更高级的查询

  • 你可以这样做

    class User( models.Model ):
        ... all the usual stuff ...
        @property
        def first_letter( self ):
            return self.name[:1]
    
    现在可以使用
    过滤器(第一个字母\u in=('p','T','R'))进行过滤了。

    第二种选择是为过滤器构建Django
    Q
    对象

    从这里开始:

    这可以用

    您还可以在运行时构建Q过滤器:

    filterList = ['P', 'T', 'R']
    query = Q()
    for letter in filterList:
        query = query | Q(name__startswith=letter)
    usersWithPTRName = User.objects.filter(query)
    

    您可以使用python
    reduce
    操作符
    内置:

    import operator
    from functools import reduce
    
    from django.db.models import Q
    
    values = ["blue", "green", "brown"]
    
    # or condition
    conditions = reduce(operator.or_, [Q(**{"categories__slug": value}) for value in values])
    
    # and condition
    conditions = reduce(operator.and_, [Q(**{"categories__slug": value}) for value in values])
    
    queryset = queryset.filter(conditions)
    

    您不能使用Django ORM对Python属性进行过滤。Django不允许您在查找中使用字段(或F对象)以外的其他内容。我认为Django Q对象会更好,但我在弄清楚如何组合两个Q对象(以及哪些对象)以获得正确的结果时遇到了一些困难。我需要的是,所有具有字段
    的对象,就像列表中的任何对象一样。鉴于上述示例,PATRICK、ROBERT、THOMAS等将是有效的结果。我似乎无法找出Q对象在paradozz870上执行“startswith any of P,t,R”的正确结构:除非这假设我正在搜索的项目数量是固定的。filterList是专门做的,因此它可以是可变大小的。我需要一些不依赖硬编码Q的东西objects@paradoz870见第二个例子谢谢。这对我很有帮助。我把它与上面Ignacio关于“reduce()”的建议结合起来使用。@catavaran:这可以用
    来实现吗?仅供参考:如果您需要使用
    &
    功能执行类似操作,请查看
    import operator
    from functools import reduce
    
    from django.db.models import Q
    
    values = ["blue", "green", "brown"]
    
    # or condition
    conditions = reduce(operator.or_, [Q(**{"categories__slug": value}) for value in values])
    
    # and condition
    conditions = reduce(operator.and_, [Q(**{"categories__slug": value}) for value in values])
    
    queryset = queryset.filter(conditions)