Django valores_lista vs valores

4 minutos de lectura

avatar de usuario
Hassan Baig

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

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

contra

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

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

  • Con la lista de valores puedes hacer if self.id in Article.objects.values_list('comment_id', flat=True): mientras usa valores necesita acceder al diccionario

    – dnaranjo

    13 mayo 2016 a las 9:20


  • @dnaranjo – Podrías, pero ¿por qué no simplemente hacerlo? Article.objects.filter(comment_id=self.id).exists()?

    – Sayse

    13 de mayo de 2016 a las 9:34


  • Esa es una respuesta para otra pregunta.

    – dnaranjo

    13 mayo 2016 a las 10:17

avatar de usuario
Alasdair

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

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

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

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

Si estás usando values_list() con un solo campo, puede utilizar flat=True para devolver un QuerySet de valores únicos en lugar de tuplas de 1:

<QuerySet [1, 2]>

  • Ah, y no hay diferencia entre los dos vis-a-vis cómo distinct() se usa eh?

    -Hassan Baig

    13 de mayo de 2016 a las 9:16

  • no, no creo distinct() funciona de manera diferente. Lo importante es con qué estructura de datos desea trabajar.

    – Alasdair

    13 de mayo de 2016 a las 9:18

  • los values() devuelve un QuerySet y no un list. Aunque el objeto devuelto por values() parece un list, no se comporta como tal en algunos casos. Por ejemplo, no será json serializable a menos que lo convirtamos en una ‘lista’

    – Abhijit Ghate

    7 de agosto de 2018 a las 11:57


  • @AbhijitGhate buen punto, he actualizado la respuesta para que quede más claro.

    – Alasdair

    7 de agosto de 2018 a las 12:20

  • Puede convertir fácilmente el retorno de values_list a una verdadera lista de Python simplemente usando el list función: list(Article.objects.values_list('comment_id', flat=True).distinct())

    – inostia

    13 mayo 2019 a las 23:08


avatar de usuario
Ibrahim Kasim

valores()

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

valores_lista()

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

distinto()

distintos se utilizan para eliminate the duplicate elementos.

Ejemplo:

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

  • Es una lista de diccionarios que se devuelve en caso de values

    -Hassan Baig

    11 de diciembre de 2016 a las 16:27

  • Solo para aclarar: distinct() elimina los elementos duplicados de los resultados de la consulta, no de la base de datos.

    – oz19

    22 de diciembre de 2019 a las 17:10

avatar de usuario
pitu

Puede obtener los diferentes valores con:

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

  • Esto será mucho más lento que usar distinct() para eliminar duplicados a nivel de base de datos.

    – Alejandro Surafel

    29 de agosto de 2020 a las 15:11

  • Además, usar set() forzará una consulta en toda la tabla, cuando un QuerySet (devuelto por distinct()) transmitirá datos solo cuando sea necesario.

    – Elektordi

    22/03/2021 a las 20:55

avatar de usuario
Kai-Kazuya Ito

“valores()” devoluciones un QuerySet de diccionarios.

Por ejemplo:

print(User.objects.all().values()) # Return all fields
# <QuerySet [{'id': 1, 'name': 'John'}, {'id': 2, 'name': 'Tom'}]>

print(User.objects.all().values("name")) # Return "name" field
# <QuerySet [{'name': 'John'}, {'name': 'Tom'}]>

“lista_valores()” devoluciones un QuerySet de tuplas.

Por ejemplo:

print(User.objects.all().values_list()) # Return all fields
# <QuerySet [(1, 'John'), (2, 'Tom')]>

print(User.objects.all().values_list("name")) # Return "name" field
# <QuerySet [('John',), ('Tom',)]>

“lista_valores()” con “plano = Verdadero” devoluciones un QuerySet de valores. *Ningún o Un campo con “plano = Verdadero” está permitido y un campo debe ser el 1er argumento con “plano = Verdadero” que debe ser el segundo argumento.

Por ejemplo:

print(User.objects.all().values_list(flat=True)) # Return "id" field
# <QuerySet [1, 2]>

print(User.objects.all().values_list("name", flat=True)) # Return "name" field
# <QuerySet ['John', 'Tom']>

print(User.objects.all().values_list(flat=True, "name")) # Error

print(User.objects.all().values_list("id", "name", flat=True)) # Error

El mejor lugar para entender la diferencia es en el documentación oficial sobre valores/values_list. Tiene muchos ejemplos útiles y lo explica muy claramente. Los documentos de Django son muy fáciles de usar.

Aquí hay un breve fragmento para mantener contentos a los revisores de SO:

valores

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

Y lea la sección que le sigue:

lista_de_valores

Esto es similar a valores () excepto que en lugar de devolver diccionarios, devuelve tuplas cuando se repite.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad