Создание дерева из самореферентных таблиц в SQLalchemy

I ' Я создаю базовую CMS во флаконе для сайта, ориентированного на iPhone, и у меня с чем-то возникают небольшие проблемы. У меня очень маленькая база данных всего с одной таблицей (страницами). Вот модель:

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 вложенными страницами?

Заранее спасибо!


РЕДАКТИРОВАТЬ: Я немного огляделся и нашел http: //www.sqlalchemy. org / docs / orm / Relations.html # adjacency-list-Relations , поэтому я добавил

children = db.relationship("Page", backref=db.backref("parent", remote_side=id))

в конец моей модели страницы . и я смотрю на то, как рекурсивно просматриваю все и добавляю это в дерево объектов. Я, вероятно, не имел смысла, но это лучший способ описать это


РЕДАКТИРОВАТЬ 2: Я попытался создать рекурсивную функцию, которая бы запускала все страницы и генерировала большой вложенный словарь со всеми страниц и их дочерних элементов, но он продолжает давать сбой в питоне, поэтому я думаю, что это просто бесконечный цикл ... вот функция

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)

у кого-нибудь есть идеи?

11
задан Tom Brunoli 5 February 2011 в 01:41
поделиться