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.

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.


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

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


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.


2

Ketik Cast to List

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

    json.dumps(list(job_reports))

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



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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.