【问题标题】:Django: Most efficient way to create a nested dictionary from querying related models?Django:通过查询相关模型创建嵌套字典的最有效方法?
【发布时间】:2016-10-04 06:10:30
【问题描述】:

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

例如,如果我有以下型号:

  • 父母
    • 儿童
      • 宠物

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

例如,“prefetch_related”是否可以用于获取所有三层,因为它用于获取两层here

让字典看起来像这样会很棒:

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

编辑:

根据要求,模型可能如下所示:

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 的样子:

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

【问题讨论】:

  • 请添加型号的代码。
  • @RahulGupta:谢谢 Rahul,我添加了模型代码。

标签: django dictionary django-queryset django-orm


【解决方案1】:

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

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]

【讨论】:

  • 感谢拉胡尔的回答。测试时出现以下错误:AttributeError: Cannot find 'childs' on Parent object, 'childs__pets' is an invalid parameter to prefetch_related()
  • 请尝试children__pets
  • 哈,我刚要发布“children_pets”有效。谢谢你帮助拉胡尔,这就是我需要的!
猜你喜欢
  • 1970-01-01
  • 2021-03-17
  • 2019-08-25
  • 1970-01-01
  • 2020-10-19
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
相关资源
最近更新 更多