Я создаю базовую CMS в колбе для сайта, ориентированного на iPhone, и у меня возникли небольшие проблемы с чем-то. У меня очень маленькая база данных всего с 1 таблицей (страницами). Вот модель:
class Page(db.Model):
__tablename__ = 'pages'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
parent_id = db.Column(db.Integer, db.ForeignKey("pages.id"), nullable=True)
Как видите, для подстраниц они просто ссылаются на другой объект страницы в поле parent_id
. То, что я пытаюсь сделать в панели администратора, - это вложенный неупорядоченный список со всеми страницами, вложенными в их родительские страницы. У меня очень мало идей о том, как это сделать. Все, о чем я могу думать, это следующее (которое будет работать (возможно, я не проверял) только на 2 уровня ниже):
pages = Page.query.filter_by(parent_id=None)
for page in pages:
if Page.query.filter_by(parent_id=page.id):
page.sub_pages = Page.query.filter_by(parent_id=page.id)
Затем я бы просто отформатировал его в список в шаблоне. Как мне заставить это работать с потенциально более чем 10 вложенными страницами?
Заранее спасибо!
EDIT: я немного осмотрелся и нашел https://www.sqlalchemy.org/docs/orm/relationships.html#adjacency-list-relationships, поэтому я добавил
children = db.relationship("Page", backref=db.backref("parent", remote_side=id))
в нижней части моей модели Page
. и я смотрю на рекурсивное прохождение всего и добавление его в дерево объектов. Я, наверное, не понял смысла, но это лучший способ, которым я могу это описать.
РЕДАКТИРОВАТЬ 2: я попытался создать рекурсивную функцию для прохождения по всем страницам и создания большого вложенного словаря со всеми страницами и их дочерними элементами, но он продолжает сбой Python, поэтому я думаю, что это просто бесконечный цикл... вот функция
def get_tree(base_page, dest_dict):
dest_dict = { 'title': base_page.title, 'content': base_page.content }
children = base_page.children
if children:
dest_dict['children'] = {}
for child in children:
get_tree(base_page, dest_dict)
else:
return
и страница, на которой я это тестирую:
@app.route('/test/')
def test():
pages = Page.query.filter_by(parent_id=None)
pages_dict = {}
for page in pages:
get_tree(page, pages_dict)
return str(pages_dict)
у кого-нибудь есть идеи?
options(joinedload_all(...))
, а затем построить свое дерево на основе parent_id. Я предполагаю, что у вас не будет миллионов элементов (т.е. сколько страниц у вас будет? 100? даже 1000? ), поэтому такой запрос не должен создавать проблем с точки зрения производительности базы данных, а также обход такого массива для построения вашего дерева не должен быть слишком ресурсоемким. 24.08.2015cascade
вrelationship
и аргументомONDELETE
в функцииforeignkey
, для которой установлено значениеCASCADE
? 02.05.2019joinedload_all
устарело и будет удален в будущем выпуске. 22.06.2020