How to dynamically compose an OR query filter in Django?

后端 未结 14 1339
清歌不尽
清歌不尽 2021-01-22 05:24

From an example you can see a multiple OR query filter:

Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))

For example, this results in:

相关标签:
14条回答
  • 2021-01-22 06:01

    easy..
    from django.db.models import Q import you model args = (Q(visibility=1)|(Q(visibility=0)&Q(user=self.user))) #Tuple parameters={} #dic order = 'create_at' limit = 10

    Models.objects.filter(*args,**parameters).order_by(order)[:limit]
    
    0 讨论(0)
  • 2021-01-22 06:05

    Found solution for dynamical field names:

    def search_by_fields(value, queryset, search_in_fields):
        if value:
            value = value.strip()
    
        if value:
            query = Q()
            for one_field in search_in_fields:
                query |= Q(("{}__icontains".format(one_field), value))
    
            queryset = queryset.filter(query)
    
        return queryset
    
    0 讨论(0)
  • 2021-01-22 06:11

    Maybe it's better to use sql IN statement.

    Article.objects.filter(id__in=[1, 2, 3])
    

    See queryset api reference.

    If you really need to make queries with dynamic logic, you can do something like this (ugly + not tested):

    query = Q(field=1)
    for cond in (2, 3):
        query = query | Q(field=cond)
    Article.objects.filter(query)
    
    0 讨论(0)
  • 2021-01-22 06:11

    This one is for dynamic pk list:

    pk_list = qs.values_list('pk', flat=True)  # i.e [] or [1, 2, 3]
    
    if len(pk_list) == 0:
        Article.objects.none()
    
    else:
        q = None
        for pk in pk_list:
            if q is None:
                q = Q(pk=pk)
            else:
                q = q | Q(pk=pk)
    
        Article.objects.filter(q)
    
    0 讨论(0)
  • 2021-01-22 06:13

    A shorter way of writing Dave Webb's answer using python's reduce function:

    # For Python 3 only
    from functools import reduce
    
    values = [1,2,3]
    
    # Turn list of values into one big Q objects  
    query = reduce(lambda q,value: q|Q(pk=value), values, Q())  
    
    # Query the model  
    Article.objects.filter(query)  
    
    0 讨论(0)
  • 2021-01-22 06:14

    In case we want to programmatically set what db field we want to query:

    import operator
    questions = [('question__contains', 'test'), ('question__gt', 23 )]
    q_list = [Q(x) for x in questions]
    Poll.objects.filter(reduce(operator.or_, q_list))
    
    0 讨论(0)
提交回复
热议问题