Как мне преобразовать 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подкласс, который возвращает словари при использовании в качестве итерации, а не объекты экземпляра модели.

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

Бернхард Валлант
источник
2

Тип приведен в список

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

    json.dumps(list(job_reports))
Саураб Чандра Патель
источник
1

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

Назовите это так -

myList = dictOfSomeData.values()
itemNumberThree = myList[2] #If there's a value in that index off course...
Идо Магор
источник
0

Проще говоря list(yourQuerySet).

Мигель де Матос
источник
2
Это дает вам список объектов, а не список dicts.
Flimm
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
ABN
источник