able to return nested dictionary using values? django
Asked Answered
G

2

6

let's say if I have a model named Blog and this is how the value works

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

but let's say if I want to make the name into another dict and get such in return

[{'id': 1, 'blog': { 'name': 'Beatles Blog'}}]

is the above possible by using value or something similiar?

I know I can do something like which would work

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

Thanks in advance for my curiosity

Glyptography answered 1/8, 2018 at 23:46 Comment(1)
Check out this solution: Nested dictionary using valuesTeodora
H
5

This is not possible using values.

The method you suggested works well.

If you have a lot of extra fields on your model, and only need those two, a performance improvement would be to first load just the fields you need using values, then perform the list comprehension on them to reformat it as you specified.

This avoids unnecessarily querying the database for fields you do not need.

Hypocaust answered 2/8, 2018 at 1:27 Comment(4)
Actually values() doesn't load the data into memory, it returns a QuerySet object, akin to a sql statement. It isn't until you iterate over the queryset (in this case the for blog in blogs part) that the query is executed and the data is loaded. Water maloooooooneCrinkleroot
@Crinkleroot You are correct. I have updated the answer with the incorrect information removed.Hypocaust
@WaterMalone got it, thx thx for the info, this is really helpful. But I am wondering as mentioned above saying query is not executed until we iterate over the queryset, you are saying it will not hit the database at this point until I do something like for blog in blogs?Glyptography
@Glyptography Yes that is right. And my point is, if you only specify the subset of fields that you need, it will be a more efficient database query.Hypocaust
I
0

Ever since Django 3.2, this is possible using JSONObject.

So in your case, you'd do:

from django.db.models.functions import JSONObject


Blog.objects.annotate(blog=JSONObject(name='name')).values('id', 'blog')

which should yield exactly what you're asking for: [{'id': 1, 'blog': { 'name': 'Beatles Blog'}}]

Illuminometer answered 17/1 at 11:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.