461

I'm sure this is a trivial operation, but I can't figure out how it's done.

There's got to be something smarter than this:

ids = [1, 3, 6, 7, 9]

for id in ids:
    MyModel.objects.filter(pk=id)

I'm looking to get them all in one query with something like:

MyModel.objects.filter(pk=[1, 3, 6, 7, 9])

How can I filter a Django query with a list of values?

2

4 Answers 4

834

From the Django documentation:

Blog.objects.filter(pk__in=[1, 4, 7])
6
  • will it raise error if we pass empty list or return no record ?
    – Rakmo
    Commented Apr 12, 2018 at 18:10
  • @OmkarDeshpande No
    – DylanYoung
    Commented Nov 8, 2018 at 16:47
  • @DylanYoung So it will return no record
    – Rakmo
    Commented Nov 8, 2018 at 18:56
  • 2
    @OmkarDeshpande Exactly. Though,if you call get(), you will get an ObjectDoesNotExist error of course.
    – DylanYoung
    Commented Nov 8, 2018 at 18:59
  • 1
    This will return a list, @Omoidashita's answer will return a dictionary of keys to objects.
    – Laizer
    Commented Nov 12, 2020 at 19:12
69

When you have list of items and you want to check the possible values from the list then you can't use =.

The sql query will be like SELECT * FROM mytable WHERE ids=[1, 3, 6, 7, 9] which is not true. You have to use in operator for this so you query will be like SELECT * FROM mytable WHERE ids in (1, 3, 6, 7, 9) for that Django provide __in operator.

1
  • 37
    +1 for a small explanation. While I know I can read the docs, that doesn't necessarily mean I understood the docs.
    – Austin A
    Commented Feb 26, 2015 at 2:00
16

From the Django documentation:

Blog.objects.in_bulk([1])
{1: <Blog: Beatles Blog>}

Blog.objects.in_bulk([1, 2])
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}

Blog.objects.in_bulk([])
{}

Blog.objects.in_bulk()
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>, 3: <Blog: Django Weblog>}

Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
{'beatles_blog': <Blog: Beatles Blog>}
1
  • 2
    This has an advantage over the accepted answer in some cases. It returns a dictionary mapping the queried field to the object.
    – Laizer
    Commented Nov 12, 2020 at 19:12
5

You can do like this.

Blog.objects.filter(pk__in=[1, 4, 7])

But you should be careful. If just one element in the list is No-integer it doesn't work. For example this is an Exception.

Blog.objects.filter(pk__in=[1, 4, 'aa', 7])

Not the answer you're looking for? Browse other questions tagged or ask your own question.