Django: Запрос к иерархической модели
Представьте, что есть модель:
class OrgUnit(models.Model):
parent = models.ForeignKey(
'self',
on_delete=models.CASCADE,
verbose_name=_('parent'),
related_name='children',
blank=True,
null=True,
)
name = models.CharField(_('name'), max_length=255)
type = models.CharField(_('type'), max_length=55, null=True, blank=True, db_index=True)
И образец иерархии:
Легко найти все магазины, если знать идентификатор кластера (cluster_id=1):
stores = OrgUnit.objects.filter(
type='store',
parent__parent_id=cluster_id
)
Также легко найти кластер по идентификатору отдела продаж (sales_department_id=5):
cluster = OrgUnit.objects.select_related('parent__parent').get(pk=sales_department_id).parent.parent
И наконец-то нашли магазины для отдела продаж:
cluster_id = OrgUnit.objects.select_related('parent').get(pk=sales_department_id).parent.parent_id
stores = OrgUnit.objects.filter(type='store', parent__parent_id=cluster_id)
Получение магазинов по id отдела продаж приведет к 2 запросам к базе данных. Я хотел бы знать, возможно ли получить магазины по id отдела продаж в одном запросе? Если да, то как?
Вы можете снова переместить иерархию вниз с помощью children, таким образом запрашивая отношение ForeignKey в обратном порядке:
stores = OrgUnit.objects.filter(
type='store',
parent__parent__children__children__pk=sales_department_id
)
Здесь мы запрашиваем OrgItem, у которых есть родитель, у которого есть родитель, для которого есть ребенок, для которого есть ребенок с первичным ключом sales_department_id.
