You could chain your queries as follows:
values = [1,2,3]
# Turn list of values into list of Q objects
queries = [Q(pk=value) for value in values]
# Take one Q object from the list
query = queries.pop()
# Or the Q object with the ones remaining in the list
for item in queries:
query |= item
# Query the model
Article.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 it
q_objects = Q(id__in=[])
# loop trough the list and create an OR condition for each item
for 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 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)
from functools import reduce
from operator import or_
from django.db.models import Q
values = [1, 2, 3]
query = reduce(or_, (Q(pk=x) for x in values))
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)
See the docs:
>>> Blog.objects.in_bulk([1])
{1: <Blog: Beatles Blog>}
>>> Blog.objects.in_bulk([1, 2])
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}
>>> Blog.objects.in_bulk([])
{}
Note that this method only works for primary key lookups, but that seems to be what you're trying to do.
So what you want is:
Article.objects.in_bulk([1, 2, 3])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With