Django values_list vs valeurs

146

Dans Django, quelle est la différence entre les deux suivants:

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

contre

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

Mon objectif est d'obtenir une liste d'identifiants de commentaires uniques sous chacun Article. J'ai lu la documentation (et en fait j'ai utilisé les deux approches). Les résultats semblent manifestement similaires.

Hassan Baig
la source
Avec values_list, vous pouvez faire if self.id in Article.objects.values_list('comment_id', flat=True):tout en utilisant des valeurs dont vous avez besoin pour accéder au dictionnaire
dnaranjo
1
@dnaranjo - Vous pourriez mais pourquoi ne pas le faire Article.objects.filter(comment_id=self.id).exists()?
Sayse
1
C'est une réponse à une question différente
dnaranjo

Réponses:

250

La values()méthode renvoie un QuerySet contenant des dictionnaires:

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

La values_list()méthode retourne un QuerySet contenant des tuples:

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

Si vous utilisez values_list()avec un seul champ, vous pouvez utiliser flat=Truepour renvoyer un QuerySet de valeurs uniques au lieu de 1-tuples:

<QuerySet [1, 2]>
Alasdair
la source
Oh et pas de différence entre les deux vis-à-vis comment distinct()on l'utilise hein?
Hassan Baig
2
Non, je ne pense pas que cela distinct()fonctionne différemment. L'important est la structure de données avec laquelle vous souhaitez travailler.
Alasdair
3
Le values()retourne a QuerySetet non a list. Bien que l'objet renvoyé par values()ressemble à un list, il ne se comporte pas comme un dans certains cas. Par exemple, il ne sera pas sérialisable json à moins que nous ne le convertissions en une `liste '
Abhijit Ghate
@AbhijitGhate bon point, j'ai mis à jour la réponse pour rendre cela plus clair.
Alasdair
2
Vous pouvez facilement convertir le retour de values_listen une vraie liste Python en utilisant simplement la listfonction:list(Article.objects.values_list('comment_id', flat=True).distinct())
inostia
55

valeurs()

Renvoie un QuerySet qui renvoie dictionaries, plutôt que des instances de modèle, lorsqu'il est utilisé en tant qu'itérable.

liste_valeurs ()

Renvoie un QuerySet qui renvoie list of tuples, plutôt que des instances de modèle, lorsqu'il est utilisé en tant qu'itérable.

distinct()

distincts sont habitués aux eliminate the duplicateéléments.

Exemple:

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
la source
2
C'est donc une liste de dictionnaires qui est retournée en cas devalues
Hassan Baig
Juste pour clarifier: distinct()élimine les éléments en double des résultats de la requête, pas de la base de données.
oz19
5

Vous pouvez obtenir les différentes valeurs avec:

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