I have a query which uses filter
but I know there is this thing called Q
but trying to play around with it, I am not sure how I can use Q
. I am not sure which one would be better but trying to know another way to do the query.
What I actually want to do is... for my queryset return I have a default field and two input fields which are options.
let's say, language in default is english, there is a location and title field. If location and title fields are available, make a query to query location, title, and language. If only location then only query location and language, if only title then only query title and language.
I have done it two ways, one with filter only which has less code...
postings = Posting.objects.filter(language='EN')
if kwargs.get('title'):
postings = postings.filter(title__icontains=kwargs.get('title'))
if kwargs.get('location'):
postings = postings.filter(location__icontains=kwargs.get('location'))
the above does work with using only filter
I am trying to see if I can do it with using Q
but cannot seem to make it work
I have something like this at the moment
if title and location:
postings = Posting.objects.filter(title__icontains=title, location__icontains=location, language='EN')
else:
queryQ = Q(posting_language='EN')
if title:
queryQ |= Q(title__icontains=title)
if location:
queryQ |= Q(location__icontains=location)
postings = Posting.objects.filter(queryQ)
can someone please give me a hand? Thanks in advance
Firstly, |
is for ORing Q
objects. You want &
for ANDing
them.
You could rewrite your filter code as:
queryQ = Q(posting_language='EN')
if title:
queryQ &= Q(title__icontains=title)
if location:
queryQ &= Q(location__icontains=location)
postings = Posting.objects.filter(queryQ)
However I don't see any real advantage of this. Personally I think your original code is more readable.