Django values_list vs values

161

Di Django, apa perbedaan antara dua berikut ini:

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

vs.

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

Tujuan saya adalah mendapatkan daftar id komentar unik di bawah masing-masing Article. Saya telah membaca dokumentasinya (dan sebenarnya telah menggunakan kedua pendekatan tersebut). Hasilnya tampak serupa.

Hassan Baig
sumber
Dengan values_list yang dapat Anda lakukan if self.id in Article.objects.values_list('comment_id', flat=True):saat menggunakan nilai yang Anda perlukan untuk mengakses kamus
dnaranjo
1
@dnaranjo - Anda bisa, tetapi mengapa tidak melakukannya Article.objects.filter(comment_id=self.id).exists()?
Sayse
1
Itu adalah jawaban untuk pertanyaan yang berbeda
dnaranjo

Jawaban:

275

The values()Metode mengembalikan QuerySet mengandung kamus:

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

The values_list()Metode mengembalikan QuerySet mengandung tupel:

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

Jika Anda menggunakan values_list()dengan satu bidang, Anda bisa menggunakan flat=Trueuntuk mengembalikan QuerySet nilai tunggal alih-alih 1-tupel:

<QuerySet [1, 2]>
Alasdair
sumber
Oh dan tidak ada perbedaan antara keduanya, bagaimana cara distinct()menggunakannya ya?
Hassan Baig
2
Tidak, menurut saya cara distinct()kerjanya tidak berbeda. Yang penting adalah struktur data mana yang ingin Anda kerjakan.
Alasdair
3
Hasil values()a QuerySetdan bukan a list. Meskipun objek yang dikembalikan values()terlihat seperti a list, tidak berperilaku seperti itu dalam beberapa kasus. Misalnya, ini tidak akan bisa bersambung json kecuali kita mengubahnya menjadi `daftar '
Abhijit Ghate
@AbhijitGhate poin bagus, saya telah memperbarui jawaban untuk memperjelasnya.
Alasdair
2
Anda dapat dengan mudah mengonversi pengembalian dari values_listke daftar Python sebenarnya hanya dengan menggunakan listfungsi:list(Article.objects.values_list('comment_id', flat=True).distinct())
inostia
61

nilai ()

Mengembalikan QuerySet yang mengembalikan dictionaries, bukan contoh model, saat digunakan sebagai iterable.

values_list ()

Mengembalikan QuerySet yang mengembalikan list of tuples, bukan contoh model, saat digunakan sebagai iterable.

berbeda()

berbeda digunakan untuk eliminate the duplicateelemen.

Contoh:

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
sumber
2
Jadi ini adalah daftar kamus yang dikembalikan dalam kasusvalues
Hassan Baig
1
Hanya untuk memperjelas: distinct()menghilangkan elemen duplikat dari hasil kueri, bukan dari database.
oz19
6

Anda bisa mendapatkan nilai yang berbeda dengan:

set(Article.objects.values_list('comment_id', flat=True))
pitu
sumber
Ini akan jauh lebih lambat daripada menggunakan distinct()untuk menghilangkan duplikat di tingkat database.
Alexander Suraphel