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.
11 Answers
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.
- 139,281
- 83
- 327
- 490
-
7yes 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 -
15this 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
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
- 3,443
- 2
- 15
- 15
-
24Or you can simplify converting to list with this `list(result)` – Adiyat Mubarak Sep 23 '15 at 09:04
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 ...
- 2,279
- 2
- 19
- 29
-
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
Type Cast to List
job_reports = JobReport.objects.filter(job_id=job_id, status=1).values('id', 'name')
json.dumps(list(job_reports))
- 11,619
- 5
- 84
- 76
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)
- 2,241
- 1
- 19
- 15
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— aQuerySetsubclass 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.
- 46,415
- 18
- 114
- 143
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...
- 544
- 1
- 5
- 13
You could define a function using model_to_dict as follows:
def queryset_to_list(qs,fields=None, exclude=None):
my_list=[]
for x in qs:
my_list.append(model_to_dict(x,fields=fields,exclude=exclude))
return my_list
Suppose your Model has following fields
id
name
email
Run following commands in django shell
>>>qs=<yourmodel>.objects.all()
>>>list=queryset_to_dict(qs)
>>>list
[{'id':1, 'name':'abc', 'email':'abc@ab.co'},{'id':2, 'name':'xyz', 'email':'xy@xy.co'}]
Say you want only id and name in the list of queryset dictionary
>>>qs=<yourmodel>.objects.all()
>>>list=queryset_to_dict(qs,fields=['id','name'])
>>>list
[{'id':1, 'name':'abc'},{'id':2, 'name':'xyz'}]
Similarly you can exclude fields in your output.
- 686
- 9
- 22
-
The method name is deceptive. It says queryset_to_dict but it returns an array! – TNT Dec 23 '20 at 07:33
-
-
1`from django.forms.models import model_to_dict` This does the job properly, could we make it more efficient? – J. Diaz Aug 11 '21 at 11:46
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())
- 458
- 5
- 6
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"]
- 7
- 1