Как мне преобразовать Django QuerySet в список dicts?


122

Как я могу преобразовать Django QuerySet в список dicts? Я не нашел ответа на этот вопрос, поэтому мне интересно, не хватает ли мне какой-то общей вспомогательной функции, которую все используют.

Ответы:


178

Используйте .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()вернуть, передав их в качестве аргументов. Также будьте осторожны, хотя похоже, что values ​​возвращает список dicts, на самом деле это a, <class 'django.db.models.query.ValuesQuerySet'>а не список.
dm03514

10
хотя на самом деле это не возвращает список
астрельцов

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

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)
Адият Мубарак

12

Если вам по какой-то причине нужны собственные типы данных (например, сериализация JSON), это мой быстрый и грязный способ сделать это:

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

Как видите, создание словаря внутри списка на самом деле не СУХОЕ, поэтому, если кто-то знает способ получше ...


Кажется, у меня это работает, data = list( blogs )а потом json.dumps( data ). Выходит массив с кучей объектов на стороне javascript, синтаксический анализ не требуется.
Артур Тарасов

3

Вы не совсем точно определяете, как должны выглядеть словари, но, скорее всего, вы имеете в виду QuerySet.values(). Из официальной документации django :

Возвращает ValuesQuerySet- QuerySetподкласс, который возвращает словари при использовании в качестве итерации, а не объекты экземпляра модели.

Каждый из этих словарей представляет объект с ключами, соответствующими именам атрибутов объектов модели.



1

Вы можете использовать values()метод в dict, который вы получили из поля модели 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.