#flask-sqlalchemy #children #backreference #self-referencing-table
Вопрос:
Я пытаюсь выбрать все дочерние записи из идентификатора записи, выбранного пользователем. Ниже приведено мое определение модели для сообщений и запрос, который выдает ошибку в заголовке. Я попробовал несколько вещей, включая сглаживание, которое выглядело многообещающе, но этот и несколько других вариантов были опробованы, но все дали ошибки.
# Post model
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime(100), nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
topic = db.Column(db.String(100), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
# thread structure using self-referencing see
# https://docs.sqlalchemy.org/en/14/orm/self_referential.html
parent_post = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=True)
child_posts = db.relationship('Post', backref='parent', lazy="joined", remote_side='Post.id') # background query
# display selected post thread route
@posts.route("/post_thread/<int:post_id>")
def post_thread(post_id):
posts = Post.query.filter(Post.id==post_id).join(Post.id==Post.parent_post).all()
# This works but to get only the selected post: posts = Post.query.where(Post.id==post_id)
return render_template('post_thread.html', posts=posts, topic="Thread")
Ответ №1:
Я написал рекурсивную функцию, которая работает, но при этом не используется связь обратных ссылок, поэтому, я думаю, это не самый эффективный способ сделать это.
# Recursive function to iterate down tree and return union of parent and children found
def union_children(post_id, posts):
print("Looking for child posts")
child_posts = Post.query.where(Post.parent_post==post_id)
if child_posts:
print("Child found")
posts = posts.union(child_posts)
for post in child_posts:
posts = union_children(post.id, posts)
return posts
@posts.route("/post_thread/<int:post_id>")
def post_thread(post_id):
posts = Post.query.where(Post.id==post_id)
posts = union_children(post_id, posts)
return render_template('post_thread.html', posts=posts, topic="Thread")