首页 > 解决方案 > 修复用户对帖子的评论功能——烧瓶应用

问题描述

我正在尝试链接我的用户、帖子和评论模型,以便在创建评论后,我希望能够列出帖子的所有评论(以及作者信息)。

在我的 jinja2 模板中:

{% for post in posts %}
    {{ post.title }}
    {{ post.content }}
    {% for comment in post.comments %}
        {{ comment.author.email }} 
        {{ comment.author.username }}
        {{ comment.content }}
    {% endfor %}
{% endfor %}

但是,我无法正确链接模型。现在我有:

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    ...

    posts = db.relationship('Post', backref='author', primaryjoin="User.id==Post.author_id")

    comments = db.relationship('Comment', backref='author', primaryjoin="User.id==Comment.author_id")

    def __repr__(self):
        return "{}, {}, {}".format(self.username, self.email)


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    content = db.Column(db.Text, nullable=False)
    ...

    comments = db.relationship('Comment', backref='post', lazy=True)


    def __repr__(self):
        return "Post(Title:'{}', Content:'{}')".format(self.title, self.content)


class Comment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    content = db.Column(db.Text, nullable=False)
    author_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)

    def __repr__(self):
        return "Comment({})".format(self.content)

但是,这是行不通的。在终端中尝试时,post.comments 返回“[ ]”(一个空列表)。总的来说,模特关系一直让我很艰难。

****已编辑****这是我要查询的一种方式的示例:

@app.route("/myposts", methods=['GET', 'POST'])
@login_required
def myposts():
    page = request.args.get('page', 1, type=int)
    user = User.query.filter_by(username=current_user.username).first_or_404()
    posts = Post.query.filter_by(author=user)\
            .order_by(Post.date_posted.desc())\
            .paginate(page=page, per_page=5)
    return render_template('myposts.html', title='My Posts', posts=posts, user=user)

标签: pythonflaskflask-sqlalchemy

解决方案


获得所有信息的一种方法是稍微更改查询以使用显式查询:

posts = db.session.query(Post, User, Comments)\
            .join(User)\
            .join(Comments)\
            .filter(Post.author==user)\
            .order_by(Post.date_posted.desc())\
            .paginate(page=page, per_page=5)

在这里,我假设 和 之间的关系User不再Comment存在。但是,即使它们是,您可以通过以下方式调试关系并获得对查询的更多控制权:

1)查看ORM生成的实际语句:

posts = db.session.query(Post, User, Comments)\
            .join(User)\
            .join(Comments)\
            .filter(Post.author==user)\
            .order_by(Post.date_posted.desc())

str(posts) # or posts.statement will print the query

2)使您的查询更加明确:

posts = db.session.query(
                Post.id, Post.content, User.id, User.username, 
                Comments.date_posted, Comments.content.label('comm_content')
             )\
            .join(User)\ #you can even make this more explicit with .join(User, Post.author_id == User.id)
            .join(Comments)\ #same as above
            .filter(Post.author==user)\
            .order_by(Post.date_posted.desc())

推荐阅读