Come posso convertire un Django QuerySet in un elenco di dict?


122

Come posso convertire un Django QuerySet in un elenco di dict? Non ho trovato una risposta a questo, quindi mi chiedo se mi manca una sorta di funzione di aiuto comune che tutti usano.

Risposte:


177

Usa il .values()metodo:

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

Nota: il risultato è un QuerySetche si comporta principalmente come un elenco, ma in realtà non è un'istanza di list. Usa list(Blog.objects.values(…))se hai davvero bisogno di un'istanza di list.


7
sì, specifichi quali campi vuoi values()restituire passandoli come argomenti. Fai anche attenzione anche se sembra che i valori restituiscano un elenco di dict in realtà è un <class 'django.db.models.query.ValuesQuerySet'>e non un elenco.
dm03514

10
questo in realtà non restituisce un elenco però
astreltsov

inoltre, non puoi ottenere i risultati dei metodi di istanza del tuo oggetto con values(), non so se esiste un buon metodo per fare lo stesso values()ma anche chiamando i metodi di istanza ?!
Asara

34

Il .values()metodo restituirà un risultato di tipo ValuesQuerySetche è in genere ciò di cui hai bisogno nella maggior parte dei casi.

Ma se lo desideri, puoi trasformarti ValuesQuerySetin un elenco Python nativo utilizzando la comprensione dell'elenco Python come illustrato nell'esempio seguente.

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

Trovo che quanto sopra aiuta se stai scrivendo unit test e hai bisogno di affermare che il valore di ritorno atteso di una funzione corrisponde al valore di ritorno effettivo, nel qual caso entrambi expected_resulte actual_resultdevono essere dello stesso tipo (ad esempio dizionario).

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result

17
Oppure puoi semplificare la conversione in lista con questolist(result)
Adiyat Mubarak,

12

Se hai bisogno di tipi di dati nativi per qualche motivo (ad esempio serializzazione JSON) questo è il mio modo rapido e sporco per farlo:

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

Come puoi vedere la costruzione del dict all'interno dell'elenco non è propriamente ASCIUTTA, quindi se qualcuno conosce un modo migliore ...


Mi sembra di averlo lavorato con data = list( blogs )e poi json.dumps( data ). Un array esce con un mucchio di oggetti sul lato javascript, nessuna analisi necessaria.
Arthur Tarasov

3

Non definisci esattamente come dovrebbero apparire i dizionari, ma molto probabilmente ti riferisci QuerySet.values(). Dalla documentazione ufficiale di Django :

Restituisce a ValuesQuerySet- una QuerySetsottoclasse che restituisce dizionari quando viene utilizzata come oggetti iterabili, piuttosto che come oggetti di istanza del modello.

Ciascuno di questi dizionari rappresenta un oggetto, con le chiavi corrispondenti ai nomi degli attributi degli oggetti del modello.


2

Digita Trasmetti a elenco

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

    json.dumps(list(job_reports))

1

Puoi utilizzare il values()metodo sul dict ottenuto dal campo del modello Django su cui effettui le query e quindi puoi accedere facilmente a ciascun campo tramite un valore di indice.

Chiamalo così -

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



0

È possibile definire una funzione utilizzando model_to_dict come segue:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.