nickbusted
nickbusted

Reputation: 1109

Q queries in Django

If I have the following query

return Table.objects.filter(Q(cond1) | Q(cond2))

is there a way to know which condition has given a specific row?

Upvotes: 0

Views: 191

Answers (2)

Josh Smeaton
Josh Smeaton

Reputation: 48710

Not really, no. Your query is roughly equivalent to the following SQL:

SELECT *
FROM Table
WHERE condition OR other_condition

Just like your django query, there is no natural indicator that will let you know which condition happened to be true for that particular relation. You either have to execute two queries, add extra information (the condition) to the relation, or use the condition itself.

c1 = Q('name__exact'='Bob')  # condition 1
c2 = Q('name__exact'='Mary') # condition 2

# use separate queries
set1 = Table.objects.filter(c1)  # meets condition 1
set2 = Table.objects.filter(c2)  # meets condition 2

# or use the natural condition
both = Table.objects.filter(c1|c2)
for item in both:
    if item.name == 'Bob':
        # condition 1
    elif item.name == 'Mary':
        # condition 2

Upvotes: 1

Ernest0x
Ernest0x

Reputation: 181

You can split your query in two queries:

qs1 = Table.objects.filter(cond1).extra(select={'condition': 'cond1'})
qs2 = Table.objects.filter(cond2).extra(select={'condition': 'cond2'})

Then create a union of the querysets:

qs12 = qs1 | qs2

EDITED: Unions are not supported between querysets with extra()

Then create a chain of your querysets:

from itertools import chain

qs12 = list(chain(qs1, qs2))

And use it like this:

for obj in qs12:
    if obj.condition == 'cond1':
        ...
    elif obj.condition == 'cond2':
        ...

Upvotes: 1

Related Questions