代码之家  ›  专栏  ›  技术社区  ›  Mez

Django过滤器-还是?

  •  241
  • Mez  · 技术社区  · 17 年前

    我该如何在django过滤器中执行“或”操作。

    基本上,我希望能够列出用户添加的项目(它们作为创建者列出)或项目已被批准的项目

    所以我基本上需要选择

    item.creator = owner or item.moderated = False
    

    我如何在Django中执行此操作(最好使用过滤器/查询集)

    6 回复  |  直到 8 年前
        1
  •  433
  •   Alex Koshelev    17 年前

    Q 允许复杂查找的对象。例子:

    from django.db.models import Q
    
    Item.objects.filter(Q(creator=owner) | Q(moderated=False))
    
        2
  •  101
  •   Andy Baker    11 年前

    您可以使用运算符直接组合查询集,而不需要Q对象:

    result = Item.objects.filter(item.creator = owner) | Item.objects.filter(item.moderated = False)
    

    (edit-我最初不确定这是否会导致额外的查询,但是@spookylukey指出,懒惰的查询集评估可以解决这个问题)

        3
  •  22
  •   Abhishek Chauhan    11 年前

    你想使过滤器动态,然后你必须使用lambda

    from django.db.models import Q
    
    brands = ['ABC','DEF' , 'GHI']
    
    queryset = Product.objects.filter(reduce(lambda x, y: x | y, [Q(brand=item) for item in brands]))
    

    reduce(lambda x, y: x | y, [Q(brand=item) for item in brands]) 等于

    Q(brand=brands[0]) | Q(brand=brands[1]) | Q(brand=brands[2]) | .....
    
        4
  •  19
  •   marxin    8 年前

    值得注意的是,可以添加 Q 表达。

    例如:

    from django.db.models import Q
    
    query = Q(first_name='mark')
    query.add(Q(email='mark@test.com'), Q.OR)
    query.add(Q(last_name='doe'), Q.AND)
    
    queryset = User.objects.filter(query)
    

    最后会出现如下查询:

    (first_name = 'mark' or email = 'mark@test.com') and last_name = 'doe'
    

    这样就不需要处理了 运算符、reduce等。

        5
  •  13
  •   jcomeau_ictx    9 年前

    类似于旧版的Answera,但有点简单,没有lambda:

    filter_kwargs = {
        'field_a': 123,
        'field_b__in': (3, 4, 5, ),
    }
    

    要过滤这两个条件,请使用 OR :

    Item.objects.filter(Q(field_a=123) | Q(field_b__in=(3, 4, 5, ))
    

    要以编程方式获得相同的结果,请执行以下操作:

    list_of_Q = [Q(**{key: val}) for key, val in filter_kwargs.items()]
    Item.objects.filter(reduce(operator.or_, list_of_Q))
    

    (为了清晰起见,这里分为两行)

    operator 在标准库中: import operator
    从字符串:

    或(a,b)--与a b相同。

    对于python3,reduce不在标准库中: from functools import reduce


    附笔。

    别忘了确保 list_of_Q 不是空的 reduce() 将在空列表上阻塞,它至少需要一个元素。

        6
  •  0
  •   Dorin Rusu    10 年前