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

1

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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 malooooooone
@stackPusher You are correct. I have updated the answer with the incorrect information removed.
@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?
@Dora 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.
1

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'}}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.