Як перетворити набір Django QuerySet у список диктів?


122

Як я можу конвертувати Django QuerySet у список диктів? Я не знайшов відповіді на це, тому мені цікаво, чи пропускаю я якусь загальну функцію помічника, якою користуються всі.

Відповіді:


176

Використовуйте .values()метод:

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

Примітка: результат - це QuerySetздебільшого поводиться як список, але насправді не є примірником list. Використовуйте, list(Blog.objects.values(…))якщо вам дійсно потрібен екземпляр list.


7
так, ви вказуєте, які поля ви хочете values()повернути, передаючи їх у якості аргументів. Будьте також обережні, хоча, схоже, значення повертає список диктує насправді а, <class 'django.db.models.query.ValuesQuerySet'>а не список.
dm03514

10
це фактично не повертає список, хоча
astreltsov

Крім того, ви не можете отримати результати примірників методів вашого об'єкта values(), я не знаю, чи є хороший метод зробити те ж саме, values()але і з викликом методів екземпляра ?!
Асара

34

.values()Метод поверне вам результат типу , ValuesQuerySetякий зазвичай то , що вам потрібно в більшості випадків.

Але за бажанням ви можете перетворитись ValuesQuerySetна рідний список Python, використовуючи розуміння списку Python, як показано в прикладі нижче.

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

Я вважаю, що вищезазначене допомагає, якщо ви пишете одиничні тести і вам потрібно стверджувати, що очікуване повернене значення функції відповідає фактичному поверненому значенню, у цьому випадку expected_resultіactual_result має бути тим же типу (наприклад , словник).

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

17
Або ви можете спростити перетворення до списку з цимlist(result)
Adiyat Mubarak

12

Якщо вам потрібні типові дані з якихось причин (наприклад, серіалізація JSON), це мій швидкий "n" брудний спосіб зробити це:

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

Як ви бачите, побудова дактики в списку насправді НЕ СУХА, тому якщо хтось знає кращий спосіб ...


Я, здається, у мене це працювало data = list( blogs )і потім json.dumps( data ). Масив виходить з купою об’єктів на стороні javascripta, не потрібний аналіз.
Артур Тарасов

3

Ви точно не визначаєте, як мають виглядати словники, але, швидше за все, ви маєте на увазі QuerySet.values(). З офіційної документації про джанго :

Повертає a ValuesQuerySet- aQuerySet підклас, який повертає словники при використанні як ітерабельних об'єктів, а не об'єктів-моделей.

Кожен із цих словників представляє об'єкт, з ключами, що відповідають назвам атрибутів модельних об'єктів.



1

Ви можете використовувати values() метод на дікті, який ви отримали з поля моделі Django, на якому ви робите запити, і тоді ви можете легко отримати доступ до кожного поля за значенням індексу.

Назвіть це так -

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



0

Ви можете визначити функцію, використовуючи model_to_dict наступним чином:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.