Chaitanya Agarwal
Chaitanya Agarwal

Reputation: 69

django : using Q objects

I have these 2 queries :

gifts = Products.objects \
    .filter(entry_query,in_stock__icontains='A-in') \
    .filter(~Q(title__icontains='Not Found'))

and

gifts1 = Products.objects \
    .filter(('city__name__iregex', 'Delhi'),in_stock__icontains='A-in') \
    .filter(~Q(title__icontains='Not Found'))

If I do gifts = gifts | gifts1 I get the following error:

error user-defined function raised exception

If i use Q objects like this:

gifts = Products.objects \
    .filter((Q(entry_query) & Q(in_stock__icontains='A-in')) | Q(('city__name__iregex', 'Delhi'),in_stock__icontains='A-in') ) \
    .filter(~Q(title__icontains = 'Not Found'))

I again get the same error

Here entry query is

(OR: ('title__iregex', u'bag'), ('description__iregex', u'bag'),('source_website_url__iregex', u'bag'))

Can someone please tell me where am I going wrong

Upvotes: 0

Views: 1145

Answers (1)

Jorge Leitao
Jorge Leitao

Reputation: 20103

The error in the first approach is because gifts1 and gifts are already QuerySets (try typeof(gifts)), so you cannot use | between them. It is like if you were using 'hi'|'goodbye'. You only use | for Q objects.

What you did the second time was almost correct, except the syntax: use | for OR and & for AND. The comma does not provide any logical operation on the Q, leading to a different argument on the filter, leading to an error.

Notice that both using & and joining filters are equivalent in Django (or are supposed to be), but your first approach of getting gift and gift1 as different QuerySets and evaluating them is different: that approach leads to two accesses (hits) to the database, while joining filters or Q objects in a single filter only hits it once.

As a rule of thumb, you should minimize the number of hits to the db.

Hope this helps

Upvotes: 1

Related Questions