Wednesday, 24 September 2014

Combine several Q objects programmatically with OR in Django ORM

Say we have dictionary coming from outside (from JSON, for example, containing some data to be used as OR clauses). It is possible to use __or__ to combine them programmatically.

from django.db import models
from operator import __or__ as OR
from django.db.models import Q

#... some code ...
clauses = [{'property':'name__exact','value':'andrew'},{'property':'name__icontains','value':'z'}, ... ]
or_params = []
for or_param in clauses:
    if 'value' in or_param.keys() and 'property' in or_param.keys():
        or_params.append(Q(**dict([(or_param['property'], or_param['value'])])))

Model.objects.filter(reduce(OR, or_params))

Many thanks to Calvin for right keywords