1

I would like to store certain fields from a QuerySet object into a python object (e.g. dictionary), but I wonder if it is possible to do this without looping, at least explicitly, in Python?

For example, if the content of the QuerySet are as follows:

>> queryset.values_list('parents', 'children', 'x', 'y')
>> [('parent1', 'child1', 1.1, 1.03), ('parent1', 'child2', 1.4, 1.05), ('parent2', 'child1', 0.1, 0.2), ('parent2', 'child2', 1.3, 2.2)]

Now, I would like to convert this into a dictionary. The actual structure of the dictionary is of secondary importance, as long as all the information is contained. E.g.:

d = {
  'child1': {
    'parent1' : [1.1, 1.03], 
    'parent2' : [0.1, 0.2], 
  ...
}

# or
d = {
  'parent1': {
    'child1': [1.1, 1.03], 
    'child2': [1.4, 1.05]
  ...
}

# or even: 
d = {
  'child1': [
    # parent1   # parent2
    (1.1, 1.03), (0.1, 0.2)
  ]
  ...
}

Of course, I can do this if I loop through the queryset in Python, but is it really necessary to do an explicit for loop? Is there a way to populate the dictionary directly from the queryset, similar to how list(queryset) gives you a list?

I mostly worry that a for loop will not scale well in terms of performance if I need to retrieve tens of thousands of similar entries. I know that possibly iteration is unavoidable, but at least I'd like to avoid doing that explicitly.

Everything I found online shows how to do this by iterating over the queryset in Python, which is clear to me, but I wonder if there are other, perhaps more performant, ways of doing this.

2
  • What about values method? docs.djangoproject.com/en/4.1/ref/models/querysets/… Commented Oct 3, 2022 at 18:54
  • I have considered it, but that still returns a queryset object. I need the output to be a python dictionary :/ Commented Oct 3, 2022 at 18:59

1 Answer 1

1

Use Serializers:

from rest_framework import serializers
class SomeModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = SomeModel
        fields = "__all__"

SomeModelSerializer(instance).data

returns

{'auto_now_add': '2018-12-20T21:34:29.494827Z',
 'foreign_key': 2,
 'id': 1,
 'many_to_many': [2],
 'normal_value': 1,
 'readonly_value': 2}

I think this solution has good performance.I trust Django REST Framework team :)

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

7 Comments

This is really interesting and something I have not considered at all. Will definitely give it a try. Thanks for the suggestion!
Your Welcome My Friend please do upvote to encourage me helping more people :)
If I understand correctly, this works on a model instance, not queryset, correct? So this is just like doing vars(instance)? Maybe I am not using it correctly, but I don't see how this does what I am going for?
You could pass to it a querset the set the many attribute to true
This is really cool! I think this is quite close to what I am trying to do. One thing about my case is that I also want to get related fields (e.g. parent__value). Is it possible to include those fields with the above ModelSerializer? Currently, it gives me an ImproperlyConfigured error saying the field name is not valid for my model.
|

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.