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

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.


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

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


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.


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

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



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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.