I have a form that allows you to pick multiple project types to filter from. For instance, say you have the project types "Research", "Training", and "Evaluation".
Basically what I'm looking to do is build a queryset using Q objects like:
projects.filter(Q(type__type="Research") | Q(type__type="Training"))
I'm just not sure how to build this without the filter() input being a string, which produces an error:
querystring = ""
for t in types:
querystring += " | Q(type__type="+t+")"
projects.filter(querystring) ## produces error: "ValueError: too many values to unpack"
So what would be a way to iterate over the types to create a queryset with Q objects?
Q object encapsulates a SQL expression in a Python object that can be used in database-related operations. Using Q objects we can make complex queries with less and simple code. For example, this Q object filters whether the question starts wiht 'what': from django.
This is because a Django QuerySet is a lazy object. It contains all of the information it needs to populate itself from the database, but will not actually do so until the information is needed.
A QuerySet is a collection of data from a database. A QuerySet is built up as a list of objects. QuerySets makes it easier to get the data you actually need, by allowing you to filter and order the data.
You are just building a string with no relationship to actual Q()
query objects; start with the first Q()
instance and add more:
query = Q(type__type=types[0])
for t in types[1:]:
query |= Q(type__type=t)
projects.filter(query)
You could also use the functools.reduce()
function to do this:
from functools import reduce
from operator import or_
query = reduce(or_, (Q(type__type=t) for t in types))
projects.filter(query)
The reduce()
call does exactly the same thing as the for
loop above; take a series of Q(..)
objects and combine them into a larger query with all the parts combined with |
or operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With