190

How can I convert a Django QuerySet into a list of dicts? I haven't found an answer to this so I'm wondering if I'm missing some sort of common helper function that everyone uses.

phoenix
  • 7,988
  • 6
  • 39
  • 45
Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382

13 Answers13

290

Use the .values() method:

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

Note: the result is a QuerySet which mostly behaves like a list, but isn't actually an instance of list. Use list(Blog.objects.values(…)) if you really need an instance of list.

phoenix
  • 7,988
  • 6
  • 39
  • 45
David Wolever
  • 148,955
  • 89
  • 346
  • 502
  • 7
    yes you specify which fields you want `values()` to return by passing them in as arguments. Also be careful although it looks like values returns a list of dicts its actually a `` and not a list. – dm03514 Oct 18 '11 at 18:31
  • 20
    this doesn't actually return a list though – astreltsov Jan 25 '17 at 03:26
  • also, you cant get the results of instance methods of your object with `values()`, I don't know if there is a good method to do the same as `values()` but also with calling the instance methods?! – Asara Oct 06 '18 at 21:55
  • This is very hard to understand. What is *Blog* and what is *object*? It would be good to see the data types of each. For example, which is the QuerySet? – Anthony Nash May 28 '21 at 09:39
38

The .values() method will return you a result of type ValuesQuerySet which is typically what you need in most cases.

But if you wish, you could turn ValuesQuerySet into a native Python list using Python list comprehension as illustrated in the example below.

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

I find the above helps if you are writing unit tests and need to assert that the expected return value of a function matches the actual return value, in which case both expected_result and actual_result must be of the same type (e.g. dictionary).

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result
arimbun
  • 3,885
  • 2
  • 19
  • 16
21

If you need native data types for some reason (e.g. JSON serialization) this is my quick 'n' dirty way to do it:

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

As you can see building the dict inside the list is not really DRY so if somebody knows a better way ...

Semmel
  • 2,526
  • 3
  • 21
  • 30
  • I seem to have got it working with `data = list( blogs )` and then `json.dumps( data )`. An array comes out with a bunch of objects on the javascript side, no parsing needed. – Arthur Tarasov Oct 18 '19 at 05:58
8

Type Cast to List

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

    json.dumps(list(job_reports))
Saurabh Chandra Patel
  • 12,712
  • 6
  • 88
  • 78
5

You need DjangoJSONEncoder and list to make your Queryset to json, ref: Python JSON serialize a Decimal object

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


blog = Blog.objects.all().values()
json.dumps(list(blog), cls=DjangoJSONEncoder)
gaozhidf
  • 2,621
  • 1
  • 22
  • 17
4

You do not exactly define what the dictionaries should look like, but most likely you are referring to QuerySet.values(). From the official django documentation:

Returns a ValuesQuerySet — a QuerySet subclass that returns dictionaries when used as an iterable, rather than model-instance objects.

Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects.

Bernhard Vallant
  • 49,468
  • 20
  • 120
  • 148
3

If you already have a query set you just use the list function to turn it into a list of dicts, eg:

list(MyModel.objects.values())

Mark B
  • 528
  • 5
  • 7
2

You can use the values() method on the dict you got from the Django model field you make the queries on and then you can easily access each field by a index value.

Call it like this -

myList = dictOfSomeData.values()
itemNumberThree = myList[2] #If there's a value in that index off course...
Ido Magor
  • 544
  • 1
  • 5
  • 14
2

You could define a function using model_to_dict as follows:

from django.forms.models import model_to_dict
def queryset_to_list(qs,fields=None, exclude=None):
    return [model_to_dict(x,fields,exclude) for x in qs]

Suppose your Model has the following fields

id
name
email

Run the following commands in Django shell

>>>qs=<yourmodel>.objects.all()
>>>list=queryset_to_list(qs)
>>>list
[{'id':1, 'name':'abc', 'email':'abc@ab.co'},{'id':2, 'name':'xyz', 'email':'xy@xy.co'}]

Say you want only the id and the name in the list of queryset dictionary

>>>qs=<yourmodel>.objects.all()
>>>list=queryset_to_list(qs,fields=['id','name'])
>>>list
[{'id':1, 'name':'abc'},{'id':2, 'name':'xyz'}]

Similarly, you can exclude fields in your output.

ABN
  • 1,024
  • 13
  • 26
1

I found even a better solution:

This was my queryset:

 queryset = TestDB.objects.values_list("country", "code")

Code above returned

<QuerySet [('Afghanistan', 'AF'), ('Albania', 'AL'), ('Algeria', 'DZ'), ('American Samoa', 'AS'), ('Andorra', 'AD'), ('Angola', 'AO'), ('Anguilla', 'AI'), ('Antarctica', 'AQ'), ('Antigua and Barbuda', 'AG'), ('Argentina', 'AR'), ('Armenia', 'AM'), ('Aruba', 'AW'), ('Australia', 'AU'), ('Austria', 'AT'), ('Azerbaijan', 'AZ'), ('Bahamas ', 'BS'), ('Bahrain', 'BH'), ('Bangladesh', 'BD'), ('Barbados', 'BB'), ('Belarus', 'BY'), '...(remaining elements truncated)...']>

and print(dict(queryset)) converted above into this:

{'Afghanistan': 'AF', 'Albania': 'AL', 'Algeria': 'DZ', 'American Samoa': 'AS', 'Andorra': 'AD', 'Angola': 'AO', 'Anguilla': 'AI', 'Antarctica': 'AQ', 'Antigua and Barbuda': 'AG', 'Argentina': 'AR', 'Armenia': 'AM', 'Aruba': 'AW', 'Australia': 'AU', 'Austria': 'AT', 'Azerbaijan': 'AZ', 'Bahamas ': 'BS', 'Bahrain': 'BH', 'Bangladesh': 'BD', 'Barbados': 'BB', 'Belarus': 'BY', 'Belgium': 'BE', 'Belize': 'BZ', 'Benin': 'BJ', 'Bermuda': 'BM', 'Bhutan': 'BT', 'Bolivia (Plurinational State of)': 'BO', 'Bonaire, Sint Eustatius and Saba': 'BQ', 'Bosnia and Herzegovina': 'BA', 'Botswana': 'BW', 'Bouvet Island': 'BV', 'Brazil': 'BR', 'British Indian Ocean Territory ': 'IO', 'Brunei Darussalam': 'BN', 'Bulgaria': 'BG', 'Burkina Faso': 'BF', 'Burundi': 'BI', 'Cabo Verde': 'CV', 'Cambodia': 'KH', 'Cameroon': 'CM', 'Canada': 'CA', 'Cayman Islands ': 'KY', 'Central African Republic ': 'CF', 'Chad': 'TD', 'Chile': 'CL', 'China': 'CN', 'Christmas Island': 'CX', 'Cocos (Keeling) Islands ': 'CC', 'Colombia': 'CO', 'Comoros ': 'KM', 'Congo (the Democratic Republic of the)': 'CD', 'Congo ': 'CG', 'Cook Islands ': 'CK', 'Costa Rica': 'CR', 'Croatia': 'HR', 'Cuba': 'CU', 'Curaçao': 'CW', 'Cyprus': 'CY', 'Czechia': 'CZ', 'Côte dIvoire': 'CI', 'Denmark': 'DK', 'Djibouti': 'DJ', 'Dominica': 'DM', 'Dominican Republic ': 'DO', 'Ecuador': 'EC', 'Egypt': 'EG', 'El Salvador': 'SV', 'Equatorial Guinea': 'GQ', 'Eritrea': 'ER', 'Estonia': 'EE', 'Eswatini': 'SZ', 'Ethiopia': 'ET', 'Falkland Islands  [Malvinas]': 'FK', 'Faroe Islands ': 'FO', 'Fiji': 'FJ', 'Finland': 'FI', 'France': 'FR', 'French Guiana': 'GF', 'French Polynesia': 'PF', 'French Southern Territories ': 'TF', 'Gabon': 'GA', 'Gambia ': 'GM', 'Georgia': 'GE', 'Germany': 'DE', 'Ghana': 'GH', 'Gibraltar': 'GI', 'Greece': 'GR', 'Greenland': 'GL', 'Grenada': 'GD', 'Guadeloupe': 'GP', 'Guam': 'GU', 'Guatemala': 'GT', 'Guernsey': 'GG', 'Guinea': 'GN', 'Guinea-Bissau': 'GW', 'Guyana': 'GY', 'Haiti': 'HT', 'Heard Island and McDonald Islands': 'HM', 'Holy See ': 'VA', 'Honduras': 'HN', 'Hong Kong': 'HK', 'Hungary': 'HU', 'Iceland': 'IS', 'India': 'IN', 'Indonesia': 'ID', 'Iran (Islamic Republic of)': 'IR', 'Iraq': 'IQ', 'Ireland': 'IE', 'Isle of Man': 'IM', 'Israel': 'IL', 'Italy': 'IT', 'Jamaica': 'JM', 'Japan': 'JP', 'Jersey': 'JE', 'Jordan': 'JO', 'Kazakhstan': 'KZ', 'Kenya': 'KE', 'Kiribati': 'KI', 'Korea (the Democratic People Republic of)': 'KP', 'Korea (the Republic of)': 'KR', 'Kuwait': 'KW', 'Kyrgyzstan': 'KG', 'Lao People Democratic Republic ': 'LA', 'Latvia': 'LV', 'Lebanon': 'LB', 'Lesotho': 'LS', 'Liberia': 'LR', 'Libya': 'LY', 'Liechtenstein': 'LI', 'Lithuania': 'LT', 'Luxembourg': 'LU', 'Macao': 'MO', 'Madagascar': 'MG', 'Malawi': 'MW', 'Malaysia': 'MY', 'Maldives': 'MV', 'Mali': 'ML', 'Malta': 'MT', 'Marshall Islands ': 'MH', 'Martinique': 'MQ', 'Mauritania': 'MR', 'Mauritius': 'MU', 'Mayotte': 'YT', 'Mexico': 'MX', 'Micronesia (Federated States of)': 'FM', 'Moldova (the Republic of)': 'MD', 'Monaco': 'MC', 'Mongolia': 'MN', 'Montenegro': 'ME', 'Montserrat': 'MS', 'Morocco': 'MA', 'Mozambique': 'MZ', 'Myanmar': 'MM', 'Namibia': 'NA', 'Nauru': 'NR', 'Nepal': 'NP', 'Netherlands ': 'NL', 'New Caledonia': 'NC', 'New Zealand': 'NZ', 'Nicaragua': 'NI', 'Niger ': 'NE', 'Nigeria': 'NG', 'Niue': 'NU', 'Norfolk Island': 'NF', 'Northern Mariana Islands ': 'MP', 'Norway': 'NO', 'Oman': 'OM', 'Pakistan': 'PK', 'Palau': 'PW', 'Palestine, State of': 'PS', 'Panama': 'PA', 'Papua New Guinea': 'PG', 'Paraguay': 'PY', 'Peru': 'PE', 'Philippines ': 'PH', 'Pitcairn': 'PN', 'Poland': 'PL', 'Portugal': 'PT', 'Puerto Rico': 'PR', 'Qatar': 'QA', 'Republic of North Macedonia': 'MK', 'Romania': 'RO', 'Russian Federation ': 'RU', 'Rwanda': 'RW', 'Réunion': 'RE', 'Saint Barthélemy': 'BL', 'Saint Helena, Ascension and Tristan da Cunha': 'SH', 'Saint Kitts and Nevis': 'KN', 'Saint Lucia': 'LC', 'Saint Martin (French part)': 'MF', 'Saint Pierre and Miquelon': 'PM', 'Saint Vincent and the Grenadines': 'VC', 'Samoa': 'WS', 'San Marino': 'SM', 'Sao Tome and Principe': 'ST', 'Saudi Arabia': 'SA', 'Senegal': 'SN', 'Serbia': 'RS', 'Seychelles': 'SC', 'Sierra Leone': 'SL', 'Singapore': 'SG', 'Sint Maarten (Dutch part)': 'SX', 'Slovakia': 'SK', 'Slovenia': 'SI', 'Solomon Islands': 'SB', 'Somalia': 'SO', 'South Africa': 'ZA', 'South Georgia and the South Sandwich Islands': 'GS', 'South Sudan': 'SS', 'Spain': 'ES', 'Sri Lanka': 'LK', 'Sudan ': 'SD', 'Suriname': 'SR', 'Svalbard and Jan Mayen': 'SJ', 'Sweden': 'SE', 'Switzerland': 'CH', 'Syrian Arab Republic': 'SY', 'Taiwan (Province of China)': 'TW', 'Tajikistan': 'TJ', 'Tanzania, United Republic of': 'TZ', 'Thailand': 'TH', 'Timor-Leste': 'TL', 'Togo': 'TG', 'Tokelau': 'TK', 'Tonga': 'TO', 'Trinidad and Tobago': 'TT', 'Tunisia': 'TN', 'Turkey': 'TR', 'Turkmenistan': 'TM', 'Turks and Caicos Islands ': 'TC', 'Tuvalu': 'TV', 'Uganda': 'UG', 'Ukraine': 'UA', 'United Arab Emirates ': 'AE', 'United States Minor Outlying Islands ': 'UM', 'United States of America ': 'US', 'Uruguay': 'UY', 'Uzbekistan': 'UZ', 'Vanuatu': 'VU', 'Bolivarian Republic of Venezuela': 'VE', 'Viet Nam': 'VN', 'Virgin Islands (British)': 'VG', 'Virgin Islands (U.S.)': 'VI', 'Wallis and Futuna': 'WF', 'Western Sahara': 'EH', 'Yemen': 'YE', 'Zambia': 'ZM', 'Zimbabwe': 'ZW', 'Åland Islands': 'AX'}

Which I think you need in your case too (I guess).

E_net4
  • 27,810
  • 13
  • 101
  • 139
Amax
  • 47
  • 8
0
values_list()¶
values_list(*fields, flat=False, named=False)

>>> Entry.objects.values_list('id', 'headline')
<QuerySet [(1, 'First entry'), ...]>
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
<QuerySet [(1, 'first entry'), ...]>
-2

Simply put list(yourQuerySet).

Miguel Carvalhais Matos
  • 1,113
  • 2
  • 13
  • 21
-2

im a newbie in python and i love @David Wolever answer

user = Blog.objects.all()
user = list(user.values("username", "id"))

in my case i use this to print username

user = Blog.objects.all()
user = list(user.values("username"))
name = []
for i in user:
    name.append(i["username"])
print(name)
# ["joe", "karen", "stuf"]
BitchBark
  • 3
  • 1