Django objects.filter() values_list() vs python list comprehension for __in query

Question:

I have a quirk(?) with Django queryset filtering:

ipdb> MagazineIssue.objects.filter(id__in=l_magazines.values_list('id'))
Out[0]: []

or

ipdb> MagazineIssue.objects.filter(id__in=[l_magazine.id for l_magazine in l_magazines])
Out[0]: [<MagazineIssue: Architecture Australia, Jan 1995 (#1)>]

and

ipdb> l_magazines.values_list('id')
Out[0]: [(1,)]
ipdb> [l_magazine.id for l_magazine in l_magazines]
Out[0]: [1]

so, how to use values_list()? (to produce):

[1]

or is python list comprehension the ‘way to go’?

Asked By: Daryl

||

Answers:

Try l_magazines.values_list('id', flat=True). That returns a list of ids instead of a list of single id tuples.

Answered By: Cloud Artisans

One thing to note is that there is a difference in the behaviour of values/values_list from a list comprehension:

  • values/values_list will yield the actual value stored in the field, that is, just the id (not the whole object)
  • if the value is a foreign key, and you have the appropriate relations set up in your model, the list comprehension will give you the object referred to by the foreign key.

Choosing the wrong one will either result in unnecessary database hits, or unnecessary faffing around, depending on what you are trying to do.

Answered By: Marcin