简体   繁体   中英

Fixing comment functionality for users to a post — flask app

I am trying to link my User, Post, and Comment models so that after the comment is created, I want to be able to list all the comments (with the authors information) for the post.

In my jinja2 template:

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

However, I am unable to get the models linking correctly. Right now I have:

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)

However, that does not work. When trying it out in the terminal, post.comments returns "[ ]" (an empty list). Overall, the model relationships have been giving me a tough time.

****Edited**** This is an example of one of the ways I want to query:

@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)

One way you can achieve getting all the information is by changing slightly your query to use explicit queries:

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)

Here I am assuming the relationship between User and Comment is no longer present. However, even if they are, some ways in which you can debug your relationships and gain more control of your queries is by:

1) Seeing the actual statement generated by the 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) Making your queries more explicit:

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())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM