django double left join + django rest 框架序列化器

Posted

技术标签:

【中文标题】django double left join + django rest 框架序列化器【英文标题】:django double left join + django rest framework serializers 【发布时间】:2019-06-11 01:40:12 【问题描述】:

我有这些模型:

class Item(models.Model):
   name = models.CharField(max_length=100)

class Group(models.Model):
   name = models.CharField(max_length=100)

class ItemGroup(models.Model):
   item = models.ForeignKey(Item, on_delete=models.CASCADE)
   group = models.ForeignKey(Group, on_delete=models.CASCADE)

意味着一个项目可以在多个组中。

我想查询所有个项目,并为每个项目返回他的组作为嵌套列表(如果项目没有出现在组中,则返回一个空列表)。

这就是我要用 sql 做的事情:

SELECT item.id, item.name, group.name
FROM items
LEFT JOIN item_group ON item.id = item_group.id
LEFT JOIN group ON group.id = item_group.group_id

(我也可以添加一个ORDER BY,用于分页,但现在没关系)。

这个查询会给我每个项目 X 数量的组,该项目也连接,并且至少有一行用于未出现在任何组中的项目(组设置为 null)。 然后,我需要手动将其转换为嵌套列表。

问题: 1. 如何用django ORM做同样的join?这是我发现的最接近的问题:django left join 但答案实际上不是左连接,而是prefetch_related,我想避免这种情况。 2. 如果我要创建一个嵌套的 dict 模型,如下所示:item: [list of groups for the item] 。有没有办法将它提供给 django rest 框架序列化程序?因为 ModelSerializer 似乎只能与查询集一起使用。

【问题讨论】:

【参考方案1】:

1) 你想要做的是与 Django 的工作方式背道而驰,这将导致比它价值更多的痛苦。我建议按照建议执行prefetch_related。您可能还想探索以下内容。这是ManyToManyField 上的文档。

class Item(models.Model):
    name = models.CharField(max_length=100)

class Group(models.Model):
   name = models.CharField(max_length=100)
   items = models.ManyToManyField(Group, through='ItemGroup')

class ItemGroup(models.Model):
   item = models.ForeignKey(Item, on_delete=models.CASCADE)
   group = models.ForeignKey(Group, on_delete=models.CASCADE)

2) 查看ListField。我认为它应该可以帮助你完成你想要的。

【讨论】:

以上是关于django double left join + django rest 框架序列化器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 1.9 中表达 sqlite LEFT OUTER JOIN?

Django order_by 导致 LEFT JOIN

将非 FK 条件添加到 Django ORM 中的 LEFT OUTER JOIN 以返回不连接的行

在 PostgreSQL 中使用 LEFT JOIN 而不是 NOT IN

left join 需要distinct吗

left join 右边没有值如何设置默认值