Jak przekonwertować zestaw Django QuerySet na listę dykt?

122

Jak mogę przekonwertować zestaw Django QuerySet na listę dykt? Nie znalazłem odpowiedzi na to pytanie, więc zastanawiam się, czy brakuje mi jakiejś typowej funkcji pomocniczej, z której wszyscy korzystają.

Mridang Agarwalla
źródło

Odpowiedzi:

178

Użyj .values()metody:

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

Uwaga: wynik jest taki, QuerySetktóry zachowuje się głównie jak lista, ale w rzeczywistości nie jest wystąpieniem list. Użyj, list(Blog.objects.values(…))jeśli naprawdę potrzebujesz wystąpienia list.

David Wolever
źródło
7
tak, określasz, które pola chcesz values()zwrócić, przekazując je jako argumenty. Bądź też ostrożny, chociaż wygląda na to, że wartości zwracają listę dykt, które są w rzeczywistości a, <class 'django.db.models.query.ValuesQuerySet'>a nie listą.
dm03514
10
to jednak nie zwraca listy
astreltsov
również nie możesz uzyskać wyników metod instancji twojego obiektu za pomocą values(), nie wiem, czy istnieje dobra metoda, aby zrobić to samo, values()ale także z wywołaniem metod instancji ?!
Asara
34

.values()Metoda zwróci państwu wynik typu ValuesQuerySet, który jest zwykle to, co trzeba w większości przypadków.

Ale jeśli chcesz, możesz przekształcić ValuesQuerySetsię w natywną listę Pythona, używając funkcji rozumienia list w języku Python, jak zilustrowano w poniższym przykładzie.

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

Uważam, że powyższe pomaga, jeśli piszesz testy jednostkowe i musisz stwierdzić, że oczekiwana wartość zwracana przez funkcję jest zgodna z rzeczywistą wartością zwracaną, w którym to przypadku oba expected_resulti actual_resultmuszą być tego samego typu (np. Słownik).

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result
Arthur Rimbun
źródło
17
Lub możesz uprościć konwersję do listy za pomocą tegolist(result)
Adiyat Mubarak
12

Jeśli z jakiegoś powodu potrzebujesz natywnych typów danych (np. Serializacji JSON), to jest mój szybki i brudny sposób, aby to zrobić:

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

Jak widać, budowanie dyktu wewnątrz listy nie jest tak naprawdę SUCHE, więc jeśli ktoś zna lepszy sposób ...

Semmel
źródło
Wydaje mi się, że mam pracę z data = list( blogs )czym json.dumps( data ). Wychodzi tablica z wieloma obiektami po stronie javascript, bez konieczności analizowania.
Arthur Tarasov
3

Nie określasz dokładnie, jak powinny wyglądać słowniki, ale najprawdopodobniej odnosisz się do nich QuerySet.values(). Z oficjalnej dokumentacji django :

Zwraca ValuesQuerySet- QuerySetpodklasę, która zwraca słowniki, gdy jest używana jako iterowalna, a nie obiekty instancji modelu.

Każdy z tych słowników reprezentuje obiekt, a klucze odpowiadają nazwom atrybutów obiektów modelu.

Bernhard Vallant
źródło
2

Wpisz Prześlij na listę

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

    json.dumps(list(job_reports))
Saurabh Chandra Patel
źródło
1

Możesz użyć values() metody na dykt, który otrzymałeś z pola modelu Django, na którym tworzysz zapytania, a następnie możesz łatwo uzyskać dostęp do każdego pola za pomocą wartości indeksu.

Nazwij to tak -

myList = dictOfSomeData.values()
itemNumberThree = myList[2] #If there's a value in that index off course...
Ido Magor
źródło
1

Co potrzeba DjangoJSONEncoderi listaby Państwa Querysetdo json, Ref: Python JSON serializowania obiektu dziesiętny

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


blog = Blog.objects.all().values()
json.dumps(list(blog), cls=DjangoJSONEncoder)
gaozhidf
źródło
0

Krótko mówiąc list(yourQuerySet).

Miguel de Matos
źródło
2
To daje listę obiektów, a nie listę nakazów.
Flimm
0

Możesz zdefiniować funkcję za pomocą model_to_dict w następujący sposób:

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
źródło