How to concatenate a list of Q objects?

3,019 views
Skip to first unread message

Daniel

unread,
Apr 6, 2010, 1:10:08 AM4/6/10
to Django users
Hi, I think that this must be super easy, but I'm kind of stumped.

I have a list qObjects = [qObject1, qObject2, qObject3]
What I'd like is to form this query: Sample.objects.filter(qObject1,
qObject2, qObject3)

How would I accomplish what I need? Thanks!

Masklinn

unread,
Apr 6, 2010, 1:48:28 AM4/6/10
to django...@googlegroups.com, Django users

Have you tried the filter you wrote above?

Aaron

unread,
Apr 6, 2010, 1:54:18 AM4/6/10
to Django users
Sample.objects.filter(*qObjects)

Vinicius Mendes

unread,
Apr 6, 2010, 7:14:00 AM4/6/10
to django...@googlegroups.com
I recommend you to read more documentation about python. It's a basic python feature. You can read more about it here:

http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/

Try this:

Sample.objects.filter(*qObjects)

______________________
Vinícius Mendes
Solucione Sistemas
http://solucione.info/



Sample.objects.filter(*qObjects)
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.


Daniel

unread,
Apr 7, 2010, 12:39:10 PM4/7/10
to Django users
Hi,

Thank you for your help everyone. I know that I need to learn python
better, and I did read those articles. What is still a bit unclear to
me, though, is how could I add an "OR" or "AND" separator between Q
objects?

So I have a list of qobjects like [qObj1, qObj2, qObj3].

What I want is something like Sample.objects.filter((qObj1 | qObj2),
qObj3)

I know that the default is for all Q objects to be "ANDed" together.
I think the join operation is not going to work here, nor is
concatenation, but is there something obvious that I'm missing?

THANK YOU :>

On Apr 6, 7:14 am, Vinicius Mendes <vbmen...@gmail.com> wrote:
> I recommend you to read more documentation about python. It's a basic python
> feature. You can read more about it here:
>

> http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-...


>
> Try this:
>
> Sample.objects.filter(*qObjects)
>
> ______________________
> Vinícius Mendes

> Solucione Sistemashttp://solucione.info/


>
> On Tue, Apr 6, 2010 at 2:54 AM, Aaron <byco...@gmail.com> wrote:
> > Sample.objects.filter(*qObjects)
>
> > On Apr 6, 1:10 am, Daniel <unagimiy...@gmail.com> wrote:
> > > Hi, I think that this must be super easy, but I'm kind of stumped.
>
> > > I have a list qObjects = [qObject1, qObject2, qObject3]
> > > What I'd like is to form this query:  Sample.objects.filter(qObject1,
> > > qObject2, qObject3)
>
> > > How would I accomplish what I need?  Thanks!
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Django users" group.
> > To post to this group, send email to django...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > django-users...@googlegroups.com<django-users%2Bunsu...@googlegroups.com>

Tom Evans

unread,
Apr 7, 2010, 1:00:59 PM4/7/10
to django...@googlegroups.com
On Wed, Apr 7, 2010 at 5:39 PM, Daniel <unagi...@gmail.com> wrote:
> Hi,
>
> Thank you for your help everyone.  I know that I need to learn python
> better, and I did read those articles.  What is still a bit unclear to
> me, though, is how could I add an "OR" or "AND" separator between Q
> objects?
>
> So I have a list of qobjects like [qObj1, qObj2, qObj3].
>
> What I want is something like Sample.objects.filter((qObj1 | qObj2),
> qObj3)
>
> I know that the default is for all Q objects to be "ANDed" together.
> I think the join operation is not going to work here, nor is
> concatenation, but is there something obvious that I'm missing?
>
> THANK YOU :>
>
>

Documentation on how to combine Q objects:
http://docs.djangoproject.com/en/1.1/topics/db/queries/#complex-lookups-with-q-objects

So you want to loop through them, and 'or' them together..

filters = [ q1, q2, q3, q4, q5 ]
q = None
for f in filters:
q = q | f if q else f
Foo.objects.filter(q)

Tom

Vinicius Mendes

unread,
Apr 7, 2010, 1:26:07 PM4/7/10
to django...@googlegroups.com
Refining a little:

filters = [q1,q2,q3,q4,q5]
q = Q()
for f in filters:
    q |= f
Foo.objects.filter(q)

Q() is identity for & and |.
 
Tom

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Daniel

unread,
Apr 7, 2010, 2:56:47 PM4/7/10
to Django users
Thanks alot guys. If I can be honest, I'm having a little trouble
digesting just this one line:

q = q | f if q else f

That line of code only allows (q1 | q2 | q3), right?

It will not allow mixing "AND" as well as "OR" (i.e., q1 & q2 | q3)?

Thanks!

On Apr 7, 1:26 pm, Vinicius Mendes <vbmen...@gmail.com> wrote:
> On Wed, Apr 7, 2010 at 2:00 PM, Tom Evans <tevans...@googlemail.com> wrote:


> > On Wed, Apr 7, 2010 at 5:39 PM, Daniel <unagimiy...@gmail.com> wrote:
> > > Hi,
>
> > > Thank you for your help everyone.  I know that I need to learn python
> > > better, and I did read those articles.  What is still a bit unclear to
> > > me, though, is how could I add an "OR" or "AND" separator between Q
> > > objects?
>
> > > So I have a list of qobjects like [qObj1, qObj2, qObj3].
>
> > > What I want is something like Sample.objects.filter((qObj1 | qObj2),
> > > qObj3)
>
> > > I know that the default is for all Q objects to be "ANDed" together.
> > > I think the join operation is not going to work here, nor is
> > > concatenation, but is there something obvious that I'm missing?
>
> > > THANK YOU :>
>
> > Documentation on how to combine Q objects:
>

> >http://docs.djangoproject.com/en/1.1/topics/db/queries/#complex-looku...


>
> > So you want to loop through them, and 'or' them together..
>
> > filters = [ q1, q2, q3, q4, q5 ]
> > q = None
> > for f in filters:
> >  q = q | f if q else f
> > Foo.objects.filter(q)
>
> Refining a little:
>
> filters = [q1,q2,q3,q4,q5]
> q = Q()
> for f in filters:
>     q |= f
> Foo.objects.filter(q)
>
> Q() is identity for & and |.
>
> > Tom
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Django users" group.
> > To post to this group, send email to django...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > django-users...@googlegroups.com<django-users%2Bunsu...@googlegroups.com>

Vinicius Mendes

unread,
Apr 7, 2010, 3:14:23 PM4/7/10
to django...@googlegroups.com
If you want to mix AND and OR, you will have to do this manually:

q = (q1 | q2) & q3


______________________
Vinícius Mendes
Solucione Sistemas
http://solucione.info/



To unsubscribe from this group, send email to django-users...@googlegroups.com.

greatlemer

unread,
Apr 8, 2010, 5:27:28 AM4/8/10
to Django users
On Apr 7, 6:26 pm, Vinicius Mendes <vbmen...@gmail.com> wrote:
> On Wed, Apr 7, 2010 at 2:00 PM, Tom Evans <tevans...@googlemail.com> wrote:

> > On Wed, Apr 7, 2010 at 5:39 PM, Daniel <unagimiy...@gmail.com> wrote:
> > > Hi,
>
> > > Thank you for your help everyone.  I know that I need to learn python
> > > better, and I did read those articles.  What is still a bit unclear to
> > > me, though, is how could I add an "OR" or "AND" separator between Q
> > > objects?
>
> > > So I have a list of qobjects like [qObj1, qObj2, qObj3].
>
> > > What I want is something like Sample.objects.filter((qObj1 | qObj2),
> > > qObj3)
>
> > > I know that the default is for all Q objects to be "ANDed" together.
> > > I think the join operation is not going to work here, nor is
> > > concatenation, but is there something obvious that I'm missing?
>
> > > THANK YOU :>
>
> > Documentation on how to combine Q objects:
>
> >http://docs.djangoproject.com/en/1.1/topics/db/queries/#complex-looku...

>
> > So you want to loop through them, and 'or' them together..
>
> > filters = [ q1, q2, q3, q4, q5 ]
> > q = None
> > for f in filters:
> >  q = q | f if q else f
> > Foo.objects.filter(q)
>
> Refining a little:
>
> filters = [q1,q2,q3,q4,q5]
> q = Q()
> for f in filters:
>     q |= f
> Foo.objects.filter(q)
>
> Q() is identity for & and |.

You could go one further and use
filters = [q1,q2,q3,q4,q5]
q = reduce(lambda x,y: x|y, filters, Q())
Foo.objects.filter(q)

--

G

Tom M

unread,
Apr 8, 2010, 8:08:12 AM4/8/10
to Django users
Just to explain

q = q | f if q else f

is using the short version of if/else, so let's expand that:

if q:
q = q | f
else:
q = f

q is only False when you have a Q object with no parameters i.e. Q()

and as you may have seen above | means OR. This is because the Q
object implements the __or__ special method.

Jared Forsyth

unread,
Apr 8, 2010, 12:22:58 PM4/8/10
to django...@googlegroups.com
Ok, if I understand correctly, you *don't want* to bitwise OR "|" them....
short answer:

qObjects = [qObject1, qObject2, qObject3]
Sample.objects.filter(*qObjects)

note the "*". This tells python "expand this list as arguments".

cheers
Jared

To unsubscribe from this group, send email to django-users...@googlegroups.com.

Daniel

unread,
Apr 8, 2010, 1:02:53 PM4/8/10
to Django users
Thank you, Tom. I understand now. I come from java and I was not
aware that such a syntax is allowed. I got the Q objects part of my
app working thanks to you guys.

Tom Evans

unread,
Apr 9, 2010, 5:22:57 AM4/9/10
to django...@googlegroups.com
On Thu, Apr 8, 2010 at 6:02 PM, Daniel <unagi...@gmail.com> wrote:
> Thank you, Tom.  I understand now.  I come from java and I was not
> aware that such a syntax is allowed.  I got the Q objects part of my
> app working thanks to you guys.
>

Just to clarify:

python:
a = c if b else d

java:
a = b ? c : d;

dfolland

unread,
Apr 9, 2010, 9:21:36 AM4/9/10
to Django users
If you are looking for "OR" then use the "Q object".

see http://docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q-objects

Степан Дибров

unread,
May 29, 2014, 10:06:34 AM5/29/14
to django...@googlegroups.com, unagi...@gmail.com
from django.db.models import Q
import operator

qs = SomeModel.objects.all()

# use reduce
rules = []
for rule_key, rule_value in calculated_rules:
    rules.append(Q(rule_key=rule_value))

if rules:
    qs = qs.filter(reduce(operator.or_, rules))

# not use it
q_collect = None
for rule_key, rule_value in calculated_rules:
    new_q = Q(rule_key=rule_value)
    if q_collect is None:
        q_collect = new_q
    else:
        q_collect = q_collect | new_q

if rules:
    qs = qs.filter(q_collect)

вторник, 6 апреля 2010 г., 9:10:08 UTC+4 пользователь Daniel написал:
Reply all
Reply to author
Forward
0 new messages