У меня есть система тегов, в которой теги существуют в иерархии. Я использовал django-mptt
для построения модели тегов. Я хочу отображать группу тегов по-разному, если каждый брат в группе является листовым узлом.
Для этого мне нужен модельный метод с именем all_siblings_leaf()
. Вот мой первый подход к этому методу:
def all_siblings_leaf(self):
"""Return True if all siblings, including self, are leaf nodes."""
siblings = self.get_siblings()
return all([sibling.is_leaf_node() for sibling in siblings])
Это работает, но для вызова get_siblings()
требуется только одно обращение к базе данных. Когда я хочу позвонить по номеру all_siblings_leaf()
, я уже запросил все теги, которые хочу использовать. Повторное использование этого метода с набором из нескольких сотен тегов означает несколько сотен новых вызовов БД.
Поскольку у меня уже есть все теги, я чувствую, что смогу получить информацию о листовых узлах без каких-либо дополнительных поездок в db. Вот что я придумал:
def all_siblings_leaf(self, all_tags):
"""Return True if all siblings including self are leaf nodes.
all_tags should be a queryset that used select_related('parent')
"""
if self.level == 0:
siblings = [t for t in all_tags if t.level == 0]
else:
siblings = [t for t in all_tags if t.parent == self.parent]
return all([sibling.is_leaf_node() for sibling in siblings])
Это работает; на странице, где этот метод используется много раз, есть только одно обращение к базе данных, измеряемое панелью инструментов отладки.
Это кажется действительно нелепым, просматривая каждый другой узел и проверяя, есть ли у него тот же родительский элемент, поскольку мы уже получили информацию о родительских элементах каждого тега. Это разумный подход или есть более простое решение? Я вызываю метод из шаблона при циклическом просмотре тегов, если это имеет значение.