1

I am working on an application in Python/Django. I am trying to make a filter by reducing a list of Q objects with Python's operator.or_ function. Unfortunately it results in a list that is combined with an AND rather than operator.or_. The problem occurs in the following code:

print 'operator.or_', operator.or_
filter = reduce(operator.or_, q_objects[key])
print key, '->', filter

The statement

print 'operator.or_', operator.or_

results in

operator.or_ <built-in function or_>

so that seems succesful. However,

filter = reduce(operator.or_, q_objects[key])
print key, '->', filter    

results in (with added formatting)

some_key -> (
        AND: 
        ('some_field__icontains', u'search string 1'), 
        ('other_field__icontains', u'search string 2')
    )

As you can see, the result has an AND rather than an OR. Can anyone see what I am doing wrong?

Regarding q_objects[key], it is created as follows:

q_dict = {'some_field__icontains': u'search string 1', 'other_field__icontains': u'search string 2'}
q_objects[key] = [Q(**q_dict)]
Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
tsteemers
  • 487
  • 1
  • 5
  • 8
  • What does `q_objects[key]` contain? Just wondering if it already has compound object with `AND`. Because when I try this with two simple Q objects, I get the result combined with `OR` as expected. – Praveen Gollakota Nov 15 '11 at 15:52
  • Thanks for your reply. I added additional information to the bottom. There doesn't seem to be an 'AND'-like object in there. – tsteemers Nov 15 '11 at 16:02

1 Answers1

2
q_objects[type] = [Q(**q_dict)]

No. You need to handle each element separately.

q_objects[type] = [Q(**{k: v}) for (k, v) in q_dict.iteritems()]
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358