Django query filter combining AND and OR with Q objects don't return the expected results

前端 未结 4 1855
心在旅途
心在旅途 2021-02-05 01:51

I try to combine AND and OR in a filter using Q objects. It looks like that the | behave like an AND. This is related to the previous annotate which is run in the same query and

4条回答
  •  忘了有多久
    2021-02-05 02:16

    Here's my example of complicated query, I hope you find it helpful

    or_condition = Q()
    and_condition = Q(company=request.user.profile.company)
    
    for field in MyModel._meta.get_fields():
        if field.name != 'created_on' and field.name != 'company':
            or_condition.add(
                Q(**{"{}__icontains".format(field.name): query}), Q.OR)
    
    and_condition.add(or_condition2, Q.AND)
    MyModel.objects.filter(and_condition)
    

    The problem with this method is that you get an empty (AND: ) case in your or_condition. It doesn't affect the query at all, but it annoys me! My current solution is as follows

    import operator
    from functools import reduce
    
    and_condition = Q(company=request.user.profile.company)
    or_condition = reduce(operator.or_, (Q(**{"{}__icontains".format(field.name): query})
                                         for field in MyModel._meta.get_fields() if field.name != 'created_on' and field.name != 'company'))
    
    and_condition.add(or_condition, Q.AND)
    MyModel.objects.filter(and_condition)
    

提交回复
热议问题