Django: Most efficient way to create a nested dictionary from querying related models?

和自甴很熟 提交于 2021-02-08 04:59:37

问题


In Django, what is the most efficient way to create a nested dictionary of data from querying related and child models?

For example, if I have the following models:

  • Parent
    • Children
      • Pets

I've seen django's model_to_dict method, and that's pretty cool, so I imagine I could loop through each level's queryset and create a bunch of DB calls on each level, for each instance, but is there a better way?

For example, could "prefetch_related" be used to get all three tiers as it is used to get two tiers here?

It would be great to get the dictionary to look something like this:

[
  {
    "name": "Peter Parent",
    "children": [
      {
        "name": "Chaden Child",
        "pets": [
          {
            "name": "Fanny",
            "type:": "fish"
          },
          {
            "name": "Buster",
            "type:": "bunny"
          }
        ]
      },
      {
        "name": "Charlete Child",
        "pets": [
          {
            "name": "Dandy",
            "type:": "dog"
          }
        ]
      }
    ]
  }
]

Edit:

By request this is what the models could look like:

class Pet(models.Model):
    name = models.CharField(max_length=50)
    type = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Child(models.Model):
    name = models.CharField(max_length=50)
    pets = models.ManyToManyField(Pet)

    def __str__(self):
        return self.name

class Parent(models.Model):
    name = models.CharField(max_length=50)
    children = models.ManyToManyField(Child)

    def __str__(self):
        return self.name

And this is what the raw sql would look like:

SELECT pa.name, ch.name, pe.name, pe.type
FROM aarc_parent pa
JOIN aarc_parent_children pc ON pc.parent_id = pa.id
JOIN aarc_child ch ON ch.id = pc.child_id
JOIN aarc_child_pets cp ON cp.child_id = ch.id
JOIN aarc_pet pe ON pe.id = cp.pet_id

回答1:


You can use prefetch_related along with list comprehensions. prefetch_related will help in avoiding extra queries every time related object is accessed.

parents = Parent.objects.all().prefetch_related('children__pets')

[{'name': parent.name, 'children': [{'name': child.name, 'pets': [{'name':pet.name, 'type':pet.type} for pet in child.pets.all()]} for child in parent.children.all()]} for parent in parents]


来源:https://stackoverflow.com/questions/37626867/django-most-efficient-way-to-create-a-nested-dictionary-from-querying-related-m

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!