Django Orm预取领域从手动加入表中有关多一关系的关系表

发布于 2025-01-19 20:14:19 字数 1120 浏览 1 评论 0原文

更改Django模型后,我正面临N-plus-1查询爆炸,我认为这是因为我必须从手动加入表中重新查询字段,

示例

class Dashboard(models.Model):
    team: models.ForeignKey = models.ForeignKey("Team", on_delete=models.CASCADE)
    items = models.ManyToManyField("Item", related_name="dashboards", through="DashboardItem")

class Item(models.Model):
    deleted: models.BooleanField = models.BooleanField(default=False)

class DashboardItem(models.Model):
    class Meta:
        unique_together = (
            "dashboard",
            "item",
        )

    dashboard = models.ForeignKey(Dashboard, on_delete=models.CASCADE)
    item = models.ForeignKey("Item", on_delete=models.CASCADE)
    combo_hash: models.CharField = models.CharField(max_length=400, null=True, blank=True)

如果我要查询一个 仪表板,知道我只能在2个查询中查看其项目,

dashboards = Dashboard.objects.filter(items__deleted==False).select_related("team").prefetch_related('items')

但我可以在代码中进行此操作,尽管有机会在仪表板或物品上进行预取。我发现我需要

DashboardItem.objects.filter(item=item,dashboard=dashboard).first().combo_hash

在加载仪表板或物品时如何通过表上的表中的表格进行预取值?

I'm facing an n-plus-1 query explosion after changing a Django model and I think it is because I am having to re-query for fields from a manual join table

As a stripped-down example

class Dashboard(models.Model):
    team: models.ForeignKey = models.ForeignKey("Team", on_delete=models.CASCADE)
    items = models.ManyToManyField("Item", related_name="dashboards", through="DashboardItem")

class Item(models.Model):
    deleted: models.BooleanField = models.BooleanField(default=False)

class DashboardItem(models.Model):
    class Meta:
        unique_together = (
            "dashboard",
            "item",
        )

    dashboard = models.ForeignKey(Dashboard, on_delete=models.CASCADE)
    item = models.ForeignKey("Item", on_delete=models.CASCADE)
    combo_hash: models.CharField = models.CharField(max_length=400, null=True, blank=True)

If I'm querying for a dashboard and know I need to see its items with only 2 queries I can do this

dashboards = Dashboard.objects.filter(items__deleted==False).select_related("team").prefetch_related('items')

but later in the code, despite having the opportunity to prefetch on dashboard or item. I find I'm needing to do

DashboardItem.objects.filter(item=item,dashboard=dashboard).first().combo_hash

How do I prefetch values on the manual through table when I load the dashboard or item?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

影子是时光的心 2025-01-26 20:14:19

您可以按表在自定义上以相同的方式进行自定义,以进行反向外键关系,因此,使用dashboarditem_set

dashboards = Dashboard.objects.select_related(
    "team"
).prefetch_related(
    "items",
    "dashboarditem_set",
)

for d in dashboards:
    combo_hash = d.dashboarditem_set.all()[0].combo_hash

与您的item> item模型相同。

You can prefetch on your custom through table the same way you do it for reverse foreign key relations, so by using dashboarditem_set:

dashboards = Dashboard.objects.select_related(
    "team"
).prefetch_related(
    "items",
    "dashboarditem_set",
)

for d in dashboards:
    combo_hash = d.dashboarditem_set.all()[0].combo_hash

It will be the same usage with your Item model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文