Django ORM prefetch field from manual join table on many-to-many relationship

Я столкнулся с взрывом n-плюс-1 запросов после изменения модели Django, и я думаю, что это потому, что мне приходится заново запрашивать поля из таблицы ручного соединения

В качестве примера

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)

Если я делаю запрос к приборной панели и знаю, что мне нужно просмотреть ее элементы всего двумя запросами, я могу сделать следующее

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

но позже в коде, несмотря на возможность предварительной выборки на dashboard или item. Я обнаружил, что мне нужно сделать

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 моделью.

Вернуться на верх