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

39,563

Solution 1

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

Solution 2

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.

Share:
39,563
Daryl
Author by

Daryl

I lead a team of Django developers in Melbourne called Common Code.

Updated on February 04, 2020

Comments

  • Daryl
    Daryl over 4 years

    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'?