Django values_list vs values
Solution 1
The values()
method returns a QuerySet containing dictionaries:
<QuerySet [{'comment_id': 1}, {'comment_id': 2}]>
The values_list()
method returns a QuerySet containing tuples:
<QuerySet [(1,), (2,)]>
If you are using values_list()
with a single field, you can use flat=True
to return a QuerySet of single values instead of 1-tuples:
<QuerySet [1, 2]>
Solution 2
values()
Returns a QuerySet that returns dictionaries
, rather than model instances, when used as an iterable.
values_list()
Returns a QuerySet that returns list of tuples
, rather than model instances, when used as an iterable.
distinct()
distinct are used to eliminate the duplicate
elements.
Example:
>>> list(Article.objects.values_list('id', flat=True)) # flat=True will remove the tuples and return the list
[1, 2, 3, 4, 5, 6]
>>> list(Article.objects.values('id'))
[{'id':1}, {'id':2}, {'id':3}, {'id':4}, {'id':5}, {'id':6}]
Solution 3
You can get the different values with:
set(Article.objects.values_list('comment_id', flat=True))
Solution 4
The best place to understand the difference is at the official documentation on values / values_list. It has many useful examples and explains it very clearly. The django docs are very user freindly.
Here's a short snippet to keep SO reviewers happy:
values
Returns a QuerySet that returns dictionaries, rather than model instances, when used as an iterable.
And read the section which follows it:
value_list
This is similar to values() except that instead of returning dictionaries, it returns tuples when iterated over.
Related videos on Youtube
![Hassan Baig](https://lh6.googleusercontent.com/-o5GQJ0wL1CU/AAAAAAAAAAI/AAAAAAAAA8A/2vXPq8k1xf4/photo.jpg?sz=256)
Comments
-
Hassan Baig over 3 years
In Django, what's the difference between the following two:
Article.objects.values_list('comment_id', flat=True).distinct()
vs
Article.objects.values('comment_id').distinct()
My goal is to get a list of unique comment ids under each
Article
. I've read the documentation (and in fact have used both approaches). The results overtly seem similar.-
dnaranjo about 8 yearsWith values_list you can do
if self.id in Article.objects.values_list('comment_id', flat=True):
while using values you need to access the dictionary -
Sayse about 8 years@dnaranjo - You could but why not just do
Article.objects.filter(comment_id=self.id).exists()
? -
dnaranjo about 8 yearsThat's an answer for a different question
-
-
Hassan Baig about 8 yearsOh and no difference among the two vis-a-vis how
distinct()
is used huh? -
Alasdair about 8 yearsNo, I don't think
distinct()
works any differently. The important thing is which data structure that you want to work with. -
Hassan Baig over 7 yearsSo it's a list of dictionaries that's returned in case of
values
-
Abhijit Ghate almost 6 yearsThe
values()
returns aQuerySet
and not alist
. Although the object returned byvalues()
looks like alist
, it doesn't behave like one in some cases. For example, it won't be json serializable unless we convert it into a `list' -
Alasdair almost 6 years@AbhijitGhate good point, I've updated the answer to make that clearer.
-
inostia about 5 yearsYou can easily convert the return from
values_list
to a true Python list by just using thelist
function:list(Article.objects.values_list('comment_id', flat=True).distinct())
-
oz19 over 4 yearsJust to clarify:
distinct()
eliminates the duplicate elements from query results, not from database. -
enchance over 4 yearsAs mentioned, if your tuple has 1 value then you can use
flat=True
. But if it has 2 values such as[('name', 'Jim')]
you can usedict(
[('name', 'Jim')])
which converts it to a dictionary with key-value pairs:{'name': 'Jim'}
. Very useful. -
l0b0 about 4 years@inostia In Django 2.2 I get "Error in argument:" when trying to convert using
list()
-
Alasdair about 4 years@l0b0 the issue is probably in the queryset itself, not the
list()
call. We can’t help with that in the comments here. If you’re still sick please open a new question and include the code, models and full traceback of the error. -
l0b0 about 4 yearsTurns out
set()
does work, so I'm just using that. -
Alexander Suraphel almost 4 yearsThis will be way slower than using
distinct()
to eliminate duplicates at database level. -
Elektordi over 3 yearsAlso, using set() will force a query on the whole table, when a QuerySet (returned by
distinct()
) will stream data only when needed.