Django:通过查询相关模型来创建嵌套字典的最有效方法? [英] Django: Most efficient way to create a nested dictionary from querying related models?

查看:36
本文介绍了Django:通过查询相关模型来创建嵌套字典的最有效方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Django中,通过查询相关模型和子模型创建嵌套的数据字典的最有效方法是什么?

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:

  • 父母
    • 儿童
      • 宠物

      我见过django的 model_to_dict 方法,这很酷,所以我想我可以遍历每个级别的查询集并在每个级别的每个实例上创建一堆数据库调用,但是还有更好的方法吗?

      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?

      例如,可以将"prefetch_related"用于获取所有三层,就像用于获取两层一样此处?

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

      根据要求,模型应该是这样的:

      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
      

      这是原始sql的样子:

      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
      

      推荐答案

      您可以将 prefetch_related 与列表推导一起使用. prefetch_related 将有助于避免每次访问相关对象时出现额外的查询.

      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]
      

      这篇关于Django:通过查询相关模型来创建嵌套字典的最有效方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆