values_list(*fields, flat=False)
This is similar to values()
except that instead of returning dictionaries, it returns tuples when iterated over. Each tuple contains the value from the respective field passed into the values_list()
call — so the first item is the first field, etc. For example:
>>> Entry.objects.values_list('id', 'headline') [(1, 'First entry'), ...]
If you only pass in a single field, you can also pass in the flat
parameter. If True
, this will mean the returned results are single values, rather than one-tuples. An example should make the difference clearer:
>>> Entry.objects.values_list('id').order_by('id') [(1,), (2,), (3,), ...] >>> Entry.objects.values_list('id', flat=True).order_by('id') [1, 2, 3, ...]
It is an error to pass in flat
when there is more than one field.
If you don’t pass any values to values_list()
, it will return all the fields in the model, in the order they were declared.
A common need is to get a specific field value of a certain model instance. To achieve that, use values_list()
followed by a get()
call:
>>> Entry.objects.values_list('headline', flat=True).get(pk=1) 'First entry'
values()
and values_list()
are both intended as optimizations for a specific use case: retrieving a subset of data without the overhead of creating a model instance. This metaphor falls apart when dealing with many-to-many and other multivalued relations (such as the one-to-many relation of a reverse foreign key) because the “one row, one object” assumption doesn’t hold.
For example, notice the behavior when querying across a ManyToManyField
:
>>> Author.objects.values_list('name', 'entry__headline') [('Noam Chomsky', 'Impressions of Gaza'), ('George Orwell', 'Why Socialists Do Not Believe in Fun'), ('George Orwell', 'In Defence of English Cooking'), ('Don Quixote', None)]
Authors with multiple entries appear multiple times and authors without any entries have None
for the entry headline.
Similarly, when querying a reverse foreign key, None
appears for entries not having any author:
>>> Entry.objects.values_list('authors') [('Noam Chomsky',), ('George Orwell',), (None,)]
Please login to continue.