How to dynamically compose an OR query filter in Django? How to dynamically compose an OR query filter in Django? django django

How to dynamically compose an OR query filter in Django?


You could chain your queries as follows:

values = [1,2,3]# Turn list of values into list of Q objectsqueries = [Q(pk=value) for value in values]# Take one Q object from the listquery = queries.pop()# Or the Q object with the ones remaining in the listfor item in queries:    query |= item# Query the modelArticle.objects.filter(query)


To build more complex queries there is also the option to use built in Q() object's constants Q.OR and Q.AND together with the add() method like so:

list = [1, 2, 3]# it gets a bit more complicated if we want to dynamically build# OR queries with dynamic/unknown db field keys, let's say with a list# of db fields that can change like the following# list_with_strings = ['dbfield1', 'dbfield2', 'dbfield3']# init our q objects variable to use .add() on itq_objects = Q(id__in=[])# loop trough the list and create an OR condition for each itemfor item in list:    q_objects.add(Q(pk=item), Q.OR)    # for our list_with_strings we can do the following    # q_objects.add(Q(**{item: 1}), Q.OR)queryset = Article.objects.filter(q_objects)# sometimes the following is helpful for debugging (returns the SQL statement)# print queryset.query


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

# For Python 3 onlyfrom functools import reducevalues = [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)