How to create a Django queryset from a list of values
Question:
I am given a list like so
a = [1, 2, 3, 4]
This list matches the id’s stored in a django model we will call Books.
I am trying to return a queryset of Books with the id’s in the list. I am thinking of using Q objects and grab them by doing something like this
Books.objects.filter(Q(id = 1) | Q(id=2) | Q(id=3) | Q(id=4))
Now i would just use the index like this:
Books.objects.filter(Q(id = a[0]) | Q(id=a[1]) | Q(id=a[2]) | Q(id=a[3]))
BUT, These list will be varying in length up to around 30 and hardcoding the index wont work, and hardcoding the query won’t satisfy the varying length of lists.
Is it possible to go this route? And if so, how can I accomplish returning the books with the id’s that match the list?
Answers:
You should use the __in
lookup [Django-doc] here:
Books.objects.filter(pk__in=a)
As the documentation says:
In a given iterable; often a list
, tuple
, or queryset
. It’s not a common use case, but strings (being iterables) are accepted.
For a simple case, use __in
lookup as per the answer above
However, Q objects connected with |
is not magic syntax, so it ought to be possible to build chains of them using loops, like
qlst = []
for x in some_iterable
qel = Q( something based on x)
qlst.append(qel)
if len(qlst) == 0:
# oops -- must handle somehow, or code below will crash
filter = qlst[0]
for qel in qlst[1:]:
filter = filter | qel
queryset = Books.objects.filter( filter)
Caveat: I’ve never actually needed to try this.
Work: this Working for me very help full this …
i have dynamic list and this code very easy my w
I am given a list like so
a = [1, 2, 3, 4]
This list matches the id’s stored in a django model we will call Books.
I am trying to return a queryset of Books with the id’s in the list. I am thinking of using Q objects and grab them by doing something like this
Books.objects.filter(Q(id = 1) | Q(id=2) | Q(id=3) | Q(id=4))
Now i would just use the index like this:
Books.objects.filter(Q(id = a[0]) | Q(id=a[1]) | Q(id=a[2]) | Q(id=a[3]))
BUT, These list will be varying in length up to around 30 and hardcoding the index wont work, and hardcoding the query won’t satisfy the varying length of lists.
Is it possible to go this route? And if so, how can I accomplish returning the books with the id’s that match the list?
You should use the __in
lookup [Django-doc] here:
Books.objects.filter(pk__in=a)
As the documentation says:
In a given iterable; often a
list
,tuple
, orqueryset
. It’s not a common use case, but strings (being iterables) are accepted.
For a simple case, use __in
lookup as per the answer above
However, Q objects connected with |
is not magic syntax, so it ought to be possible to build chains of them using loops, like
qlst = []
for x in some_iterable
qel = Q( something based on x)
qlst.append(qel)
if len(qlst) == 0:
# oops -- must handle somehow, or code below will crash
filter = qlst[0]
for qel in qlst[1:]:
filter = filter | qel
queryset = Books.objects.filter( filter)
Caveat: I’ve never actually needed to try this.
Work: this Working for me very help full this …
i have dynamic list and this code very easy my w