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.


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]>

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}]

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))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.