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:
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]
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
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)
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)
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)
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))