Bagaimana cara mengubah QuerySet Django menjadi daftar dicts?

122

Bagaimana saya dapat mengubah QuerySet Django menjadi daftar dicts? Saya belum menemukan jawaban untuk ini jadi saya bertanya-tanya apakah saya kehilangan semacam fungsi pembantu umum yang digunakan semua orang.

Mridang Agarwalla
sumber

Jawaban:

177

Gunakan .values()metode:

>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

Catatan: hasilnya adalah QuerySetyang sebagian besar berperilaku seperti daftar, tetapi sebenarnya bukan instance dari list. Gunakan list(Blog.objects.values(…))jika Anda benar-benar membutuhkan contoh list.

David Wolever
sumber
7
ya, Anda menentukan bidang mana yang ingin Anda values()kembalikan dengan meneruskannya sebagai argumen. Juga berhati-hatilah meskipun sepertinya nilai mengembalikan daftar dicts itu sebenarnya <class 'django.db.models.query.ValuesQuerySet'>dan bukan daftar.
dm03514
10
ini sebenarnya tidak mengembalikan daftar
astreltsov
juga, Anda tidak bisa mendapatkan hasil dari metode contoh objek Anda dengan values(), saya tidak tahu apakah ada metode yang baik untuk melakukan hal yang sama values()tetapi juga dengan memanggil metode contoh ?!
Asara
34

The .values()Metode akan kembali Anda hasil dari jenis ValuesQuerySetyang biasanya apa yang Anda butuhkan dalam kebanyakan kasus.

Tetapi jika Anda mau, Anda bisa berubah ValuesQuerySetmenjadi daftar Python asli menggunakan pemahaman daftar Python seperti yang diilustrasikan pada contoh di bawah ini.

result = Blog.objects.values()             # return ValuesQuerySet object
list_result = [entry for entry in result]  # converts ValuesQuerySet into Python list
return list_result

Saya menemukan bantuan di atas jika Anda menulis tes unit dan perlu menegaskan bahwa nilai kembalian yang diharapkan dari suatu fungsi cocok dengan nilai kembalian aktual, dalam hal ini keduanya expected_resultdan actual_resultharus dari jenis yang sama (misalnya kamus).

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result
Arthur Rimbun
sumber
17
Atau Anda dapat menyederhanakan konversi ke daftar dengan inilist(result)
Adiyat Mubarak
12

Jika Anda memerlukan tipe data asli karena alasan tertentu (misalnya serialisasi JSON) ini adalah cara cepat 'n' saya untuk melakukannya:

data = [{'id': blog.pk, 'name': blog.name} for blog in blogs]

Seperti yang Anda lihat, membangun dict di dalam daftar tidak terlalu KERING jadi jika ada yang tahu cara yang lebih baik ...

Semmel
sumber
Sepertinya saya sudah membuatnya berfungsi data = list( blogs )dan kemudian json.dumps( data ). Sebuah array keluar dengan sekumpulan objek di sisi javascript, tidak perlu parsing.
Arthur Tarasov
3

Anda tidak benar-benar mendefinisikan seperti apa bentuk kamus itu, tetapi kemungkinan besar Anda mengacu pada QuerySet.values(). Dari dokumentasi resmi django :

Mengembalikan a ValuesQuerySet- QuerySetsubclass yang mengembalikan kamus saat digunakan sebagai objek iterable, bukan objek contoh model.

Masing-masing kamus tersebut mewakili sebuah objek, dengan kunci yang sesuai dengan nama atribut objek model.

Bernhard Vallant
sumber
2

Ketik Cast to List

    job_reports = JobReport.objects.filter(job_id=job_id, status=1).values('id', 'name')

    json.dumps(list(job_reports))
Saurabh Chandra Patel
sumber
1

Anda dapat menggunakan values()metode pada dikt yang Anda peroleh dari bidang model Django tempat Anda membuat kueri dan kemudian Anda dapat dengan mudah mengakses setiap bidang dengan nilai indeks.

Sebut saja seperti ini -

myList = dictOfSomeData.values()
itemNumberThree = myList[2] #If there's a value in that index off course...
Ido Magor
sumber
1

Anda perlu DjangoJSONEncoderdan listmembuat Anda Querysetmenjadi json, ref: Python JSON membuat serial objek Desimal

import json
from django.core.serializers.json import DjangoJSONEncoder


blog = Blog.objects.all().values()
json.dumps(list(blog), cls=DjangoJSONEncoder)
gaozhidf.dll
sumber
0

Sederhananya list(yourQuerySet).

Miguel de Matos
sumber
2
Ini memberi Anda daftar objek, bukan daftar penis.
Flimm
0

Anda dapat mendefinisikan fungsi menggunakan model_to_dict sebagai berikut:

def queryset_to_dict(qs,fields=None, exclude=None):
    my_array=[]
    for x in qs:
        my_array.append(model_to_dict(x,fields=fields,exclude=exclude))
    return my_array
ABN
sumber