You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Django查询生成以父模型名称为键的子模型值字典?

如何生成以Kid名称为键、玩具元组列表为值的Django字典

嘿,我来帮你搞定这个需求!基于你给出的一对多模型,我们可以高效生成目标字典,还能避免常见的N+1查询问题,具体实现如下:

先补全规范的模型代码(Django 2.0+需要on_delete参数)

class Kid(models.Model):
    name = models.CharField(max_length=200)

class Toy(models.Model):
    name = models.CharField(max_length=200)
    material = models.CharField(max_length=200)
    owner = models.ForeignKey(Kid, on_delete=models.CASCADE)  # 补充on_delete参数,符合Django规范

高效生成目标字典的代码

我们用prefetch_related预加载关联数据,避免多次查询数据库,然后通过字典推导式快速构建结果:

# 预加载所有孩子及其对应的玩具,一次性查询数据库
kids_with_toys = Kid.objects.prefetch_related('toy_set').all()

# 生成目标字典
kid_toys_dict = {
    kid.name: [(toy.name, toy.material) for toy in kid.toy_set.all()]
    for kid in kids_with_toys
}

代码说明

  • prefetch_related('toy_set'):Django会一次性加载所有Kid关联的Toy对象,相比逐个Kid查询玩具,能大幅减少数据库请求次数,数据量越大优势越明显。
  • 字典推导式:遍历每个Kid,以孩子的name作为键,用列表推导式把该孩子的所有玩具转换成(玩具名, 材质)的元组列表作为值。

可选优化:设置related_name

如果给Toy的ForeignKey设置related_name,代码会更易读:

# 修改Toy模型的ForeignKey字段
owner = models.ForeignKey(Kid, on_delete=models.CASCADE, related_name='toys')

# 此时生成字典的代码可以改成
kid_toys_dict = {
    kid.name: [(toy.name, toy.material) for toy in kid.toys.all()]
    for kid in kids_with_toys
}

示例结果

假设数据库里有这些数据:

  • 孩子"小明"有玩具("积木", "塑料")、("玩偶", "毛绒")
  • 孩子"小红"有玩具("遥控车", "金属")

生成的字典会是这样:

{
    "小明": [("积木", "塑料"), ("玩偶", "毛绒")],
    "小红": [("遥控车", "金属")]
}

内容的提问来源于stack exchange,提问作者bwrabbit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:36:07