Jinja2 For循环中的烧瓶形式处理

时间:2019-07-21 21:12:38

标签: python html python-3.x flask jinja2

我有一个博客类型的应用程序,其中主页显示带有一些信息并以Add Comment形式的帖子。该表单旨在针对该特定帖子写到models.py中的Comments()模型。

问题:因为我正在循环浏览home.html中的帖子,所以home中的routes.py函数无法使用post.id。因此,在验证表单后,注释将应用于所有帖子,而不仅仅是添加注释的帖子。

问题:如何从Jinja post.id的{​​{1}}函数中获取相关的home并将评论应用于特定帖子,而不只是首页上的所有帖子?我没有看到我的逻辑/语法错误-我在这里想念什么?谢谢

forloopThe resulting error当然有意义,因为该应用程序不知道我们在AttributeError: 'function' object has no attribute 'id' 的Jinja2 forloop中引用的是哪个帖子。

这是home.html中的Comments数据库模型:

models.py

这是我在class Comments(db.Model): comment_id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, nullable=True, primary_key=False) post_id = db.Column(db.Integer, nullable=True, primary_key=False) comment = db.Column(db.String(2000), unique=False, nullable=True) comment_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) class Meta: database = db def fetch_post_comments(self, post_id): comments = Comments.query.filter(Comments.post_id==post_id) return comments def fetch_user(self, user_id): user = User.query.filter(User.id==user_id).first_or_404() return user.username def __repr__(self): return f"Comments ('{self.user_id}', '{self.post_id}', '{self.comment}', '{self.comment_date}')" 中的home函数:

routes.py

这是我的@app.route("/") @app.route("/home", methods=['GET', 'POST']) @login_required def home(): page = request.args.get('page', 1, type=int) posts = Post.query.order_by(Post.date_posted.desc()).paginate(page=page, per_page=5) comment_form = CommentForm() def add_comment(post_id): if comment_form.validate_on_submit(): new_comment = Comments(user_id=current_user.id, post_id=post_id, comment=comment_form.comment_string.data) db.session.add(new_comment) db.session.commit() flash('HOT TAKE! Posted your comment.', 'success') # return redirect(url_for('post', post_id=post.id)) def get_upvote_count(post_id): count = Vote.query.filter(Vote.post_id==post_id).count() return count def get_flag_count(post_id): count = Flag.query.filter(Flag.post_id == post_id).count() return count def get_comment_count(post_id): count = Comments.query.filter(Comments.post_id == post_id).count() return count def get_favorite_count(post_id): count = Favorites.query.filter(Favorites.post_id == post_id).count() return count def get_youtube_id_from_url(url): video_id = url.split('v=')[1] if '&' in video_id: video_id = video_id.split('&')[0] base_url = "https://www.youtube.com/embed/" return base_url + video_id def get_spotify_embed_url(url): track_or_playlist = url.split('https://open.spotify.com/')[1].split('/')[0] base_url = f"https://open.spotify.com/embed/{track_or_playlist}/" spotify_id = url.split('https://open.spotify.com/')[1].split('/')[1] embed_url = base_url + spotify_id return embed_url return base_url + video_id return render_template('home.html', posts=posts, get_upvote_count=get_upvote_count, get_comment_count=get_comment_count, get_flag_count=get_flag_count, get_favorite_count=get_favorite_count, comment_form=comment_form, add_comment=add_comment, get_youtube_id_from_url=get_youtube_id_from_url, get_spotify_embed_url=get_spotify_embed_url)

home.html

1 个答案:

答案 0 :(得分:2)

几个选项:

  1. post.id作为参数或arg添加到url中,这是arg方法:

将网址添加到表单中,并将post.id设置为arg:

<form method="POST" action="{{url_for('home', post_id=post.id)}}" enctype="multipart/form-data">

在路线中:

new_comment = Comments(user_id=current_user.id,
                               post_id=request.args.get('post_id', type=int),
                               comment=comment_form.comment_string.data)

OR

  1. 在表单中添加一个隐藏字段,并将其值设置为post.id

在表单上添加一个隐藏字段:

post_id = HiddenField()

您需要替换CSRF渲染(hidden_tag()),以防止自动渲染post_id字段:

{{ comment_form.csrf_token }} 

接下来,设置您的隐藏字段数据的值(此功能的积分为this答案):

{% set p = comment_form.post_id.process_data(post.id) %}
{{ comment_form.post_id() }}

最后,在路由中,(删除add_comment声明):

def home():
    # Omitted ...

    if comment_form.validate_on_submit():
        new_comment = Comments(user_id=current_user.id,
                               post_id=comment_form.post_id.data,
                               comment=comment_form.comment_string.data)
        db.session.add(new_comment)
        # etc...

希望这会有所帮助,请注意,它尚未经过测试