Django values_list vs valores

146

En Django, ¿cuál es la diferencia entre los dos siguientes:

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

vs

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

Mi objetivo es obtener una lista de identificadores de comentarios únicos debajo de cada uno Article. He leído la documentación (y de hecho he usado ambos enfoques). Los resultados abiertamente parecen similares.

Hassan Baig
fuente
Con valores_lista que puede hacer if self.id in Article.objects.values_list('comment_id', flat=True):mientras usa valores que necesita para acceder al diccionario
dnaranjo
1
@dnaranjo - Podrías, pero ¿por qué no simplemente hacerlo Article.objects.filter(comment_id=self.id).exists()?
Sayse
1
Esa es una respuesta para una pregunta diferente
dnaranjo

Respuestas:

250

El values()método devuelve un QuerySet que contiene diccionarios:

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

El values_list()método devuelve un QuerySet que contiene tuplas:

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

Si está usando values_list()un solo campo, puede usar flat=Truepara devolver un QuerySet de valores únicos en lugar de 1-tuplas:

<QuerySet [1, 2]>
Alasdair
fuente
Ah, y no hay diferencia entre los dos frente a cómo distinct()se usa, ¿eh?
Hassan Baig
2
No, no creo que distinct()funcione de manera diferente. Lo importante es con qué estructura de datos desea trabajar.
Alasdair
3
El values()devuelve a QuerySety no a list. Aunque el objeto devuelto por values()parece un a list, en algunos casos no se comporta como tal. Por ejemplo, no será json serializable a menos que lo convirtamos en una 'lista'
Abhijit Ghate
@AbhijitGhate buen punto, he actualizado la respuesta para aclarar eso.
Alasdair
2
Puede convertir fácilmente el retorno de values_lista una verdadera lista de Python simplemente usando la listfunción:list(Article.objects.values_list('comment_id', flat=True).distinct())
inostia
55

valores()

Devuelve un QuerySet que devuelve dictionaries, en lugar de instancias de modelo, cuando se usa como iterable.

valores_lista ()

Devuelve un QuerySet que devuelve list of tuples, en lugar de instancias de modelo, cuando se usa como iterable.

distinto()

distintos se utilizan para eliminate the duplicateelementos.

Ejemplo:

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
fuente
2
Entonces, es una lista de diccionarios que se devuelve en caso devalues
Hassan Baig
Solo para aclarar: distinct()elimina los elementos duplicados de los resultados de la consulta, no de la base de datos.
oz19
5

Puede obtener los diferentes valores con:

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