在更改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
加载仪表板或项目时,如何预取手动直通表上的值?
您可以像对反向外键关系进行预取一样,对自定义直通表进行预取,因此使用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
型号使用相同。