Reputation: 10564
arr = [
{id: 1, filename: "a"},
{id: 2, filename: "b"},
]
If I wanted to check if a Django table has 2 items with properties corresponding to the above, I could do:
for n in arr:
e = MyTable.objects.filter(id=n["id"], filename=n["filename"]).exists()
if not e: # raise error
But this requires to do one query for each item in the array.
How can I do this in a single query?
I was thinking to chain Q
s like this:
Q(id=n['id'],filename=n['filename']) | Q(id=n['id'],filename=n['filename']) | ...for each item in array
But then how I could I check if each separate Q returns at least one entry?
I don't care about looping over arr as long as I don't do a query for each iteration.
Upvotes: 3
Views: 1320
Reputation: 362
Make a list of all the ids
and filenames
, then use __in
https://docs.djangoproject.com/en/2.2/ref/models/querysets/#in
ids = [item.get('id') for item in arr]
filenames = [item.get('filename') for item in arr]
qs = MyTable.objects.filter(id__in=ids, filename__in=filenames)
assert qs.count() == len(arr)
Upvotes: 2
Reputation: 476567
Based on your comment, the items in arr
all have a distinct id
, so we can count the number of items that satisfy this condition. We know that this should be the same as the number of dictionaries in arr
, since each Q(id=..., ...)
can satisfy at most one record:
from functools import reduce
from operator import or_
MyTable.objects.filter(
reduce(or_, [Q(id=n['id'],filename=n['filename']) for n in arr])
).count() == len(arr)
Upvotes: 4