Django values_list vs values

146

No Django, qual é a diferença entre os dois seguintes:

Article.objects.values_list('comment_id', flat=True).distinct()

vs

Article.objects.values('comment_id').distinct()

Meu objetivo é obter uma lista de IDs de comentários exclusivos em cada um Article. Eu li a documentação (e, de fato, usei as duas abordagens). Os resultados abertamente parecem semelhantes.

Hassan Baig
fonte
Com values_list você pode fazer if self.id in Article.objects.values_list('comment_id', flat=True):enquanto estiver usando os valores que você precisa para acessar o dicionário
dnaranjo
1
@dnaranjo - Você poderia, mas por que não fazer Article.objects.filter(comment_id=self.id).exists()?
Sayse
1
Isso é uma resposta para uma pergunta diferente
dnaranjo

Respostas:

250

O values()método retorna um QuerySet contendo dicionários:

<QuerySet [{'comment_id': 1}, {'comment_id': 2}]>

O values_list()método retorna um QuerySet contendo tuplas:

<QuerySet [(1,), (2,)]>

Se você estiver usando values_list()um único campo, poderá flat=Trueretornar um QuerySet de valores únicos em vez de 1-tupla:

<QuerySet [1, 2]>
Alasdair
fonte
Ah, e não há diferença entre os dois em relação a como distinct()é usado, hein?
Hassan Baig
2
Não, acho que não distinct()funciona de maneira diferente. O importante é com qual estrutura de dados você deseja trabalhar.
Alasdair
3
As values()retorna um QuerySete não um list. Embora o objeto retornado por se values()pareça com um list, ele não se comporta como um em alguns casos. Por exemplo, ele não pode ser serializado pelo json, a menos que o convertamos em uma `lista '
Abhijit Ghate
@AbhijitGhate bom ponto, atualizei a resposta para deixar isso mais claro.
Alasdair
2
Você pode facilmente converter o retorno values_lista uma verdadeira lista Python, usando apenas a listfunção:list(Article.objects.values_list('comment_id', flat=True).distinct())
inostia
54

valores ()

Retorna um QuerySet que retorna dictionaries, em vez de instâncias de modelo, quando usado como iterável.

values_list ()

Retorna um QuerySet que retorna list of tuples, em vez de instâncias de modelo, quando usado como iterável.

distinto ()

distintos são usados ​​para eliminate the duplicateelementos.

Exemplo:

Article.objects.values_list('id', flat=True) # flat=True will remove the tuples and return the list   
[1, 2, 3, 4, 5, 6]

Article.objects.values('id')
[{'id':1}, {'id':2}, {'id':3}, {'id':4}, {'id':5}, {'id':6}]
Ibrahim Kasim
fonte
2
Portanto, é uma lista de dicionários retornados no caso devalues
Hassan Baig
Apenas para esclarecer: distinct()elimina os elementos duplicados dos resultados da consulta, não do banco de dados.
oz19
5

Você pode obter os diferentes valores com:

set(Article.objects.values_list('comment_id', flat=True))
pitu
fonte