I couldn’t figure out what to title this post, but this victory felt sweet.
I wanted to make a searchable, sorted list of an arbitrary amount of fields to check against.
Normally, we use a Q object to get to the | “or” operator.
Person.objects.filter( Q(first_name__icontains='Yuji') | Q(last_name__icontains='Tomita')
But I wanted to use dynamic field names so that I can use this same ‘factory’ on other models.
With much needed prodding in the right direction by mattmcc, I figured it out.
The much needed key was how to use keyword arguments:
Person.objects.filter(first_name__icontains=’Yuji’)
is equal to:
Person.objects.filter( **{‘first_name__icontains’:'Yuji’})
Therefore, I could create as many Q objects as I wanted in a list.
q_list = []
for q in query_string.split(‘ ‘):
for field in fields:
q_list.append( Q(**{field+’__icontains’: q})
query = model.objects.filter( reduce(operator.or_, q_list)
Bam!
2 responses so far ↓
sublimevelo // September 30, 2009 at 6:57 pm |
Thanks for this! I was trying to do exactly the same thing. This has saved me a lot of time.
Yuji // September 30, 2009 at 7:06 pm |
Hey man, I’m glad it helped. I didn’t write it very well, since I had already spent hours trying to figure it out.
Enjoy!