Python 金贾2号循环中的瓶形处理
我有一个博客类型的应用程序,其中主页显示带有一些信息和Python 金贾2号循环中的瓶形处理,python,html,python-3.x,flask,jinja2,Python,Html,Python 3.x,Flask,Jinja2,我有一个博客类型的应用程序,其中主页显示带有一些信息和添加评论的帖子。该表单旨在为该特定帖子在models.py中写入我的Comments()model 问题是:由于我在home.html中循环浏览帖子,因此routes.py中的home函数无法使用post.id。因此,当表单被验证时,注释将应用于所有帖子,而不仅仅是添加注释的帖子 问题:我如何从Jinjaforloop获取home函数中的相关post.id,并将注释应用于特定的帖子,而不仅仅是主页上的所有帖子??我没有看到我的逻辑/语法错误-
添加评论的帖子。该表单旨在为该特定帖子在models.py中写入我的Comments()
model
问题是:由于我在home.html中循环浏览帖子,因此routes.py
中的home
函数无法使用post.id。因此,当表单被验证时,注释将应用于所有帖子,而不仅仅是添加注释的帖子
问题:我如何从Jinjaforloop
获取home
函数中的相关post.id
,并将注释应用于特定的帖子,而不仅仅是主页上的所有帖子??我没有看到我的逻辑/语法错误-我在这里遗漏了什么?谢谢
结果错误
:AttributeError:“function”对象没有属性“id”
这当然是有意义的,因为应用程序不知道我们在home.html中的Jinja2 forloop中引用了什么帖子
以下是models.py中的注释db模型:
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}')"
@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)
这是我在routes.py中的home
函数:
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}')"
@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
{% extends "layout.html" %}
{% block content %}
{% for post in posts.items %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ url_for('static', filename='profile_pics/' + post.author.image_file) }}">
<div class="media-body">
<div class="article-metadata">
<div align="left">
<a class="mr-2 text-secondary" href="{{ url_for('user_posts', username=post.author.username) }}">{{ post.author.username }}</a>
</div>
<div align="left">
<small class="text-muted">Posted on: {{ post.date_posted.strftime('%Y-%m-%d') }}</small>
</div>
<div align="right">
<a class="mr-2 text-secondary" href="{{ url_for('flag', post_id=post.id, user_id=current_user.id) }}">Flag Post</a>
</div>
<div align="right">
<a class="mr-2 text-secondary" href="{{ url_for('add_favorite', post_id=post.id, user_id=current_user.id) }}">Favorite Post ({{ get_favorite_count(post.id) }})</a>
</div>
<div align="right">
<a class="mr-2 text-secondary" href="{{ url_for('post', post_id=post.id) }}">Comments ({{ get_comment_count(post.id) }})</a>
</div>
</div>
<h3><a class="article-title" href="{{ url_for('post', post_id=post.id) }}">{{ post.title }}</a></h3>
<p class="article-content justify-content-center">{{ post.content }}</p>
<br>
{% for url in post.urls.split('||') %}
{% if 'youtube.com' in url %}
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item"
src="{{ get_youtube_id_from_url(url) }}" allowfullscreen="" frameborder="0">
</iframe>
</div>
<a href="{{ url }}">Link</a>
{% elif 'soundcloud.com' in url %}
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" scrolling="no" frameborder="no"
src="{{ 'https://w.soundcloud.com/player/?url=' + url }}">
</iframe>
</div>
<a href="{{ url }}">Link</a>
{% elif 'spotify.com' in url %}
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item"
src="{{ get_spotify_embed_url(url) }}" allowfullscreen allow="encrypted-media">
</iframe>
</div>
<a href="{{ url }}">Link</a>
{% elif 'vimeo.com' in url %}
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" scrolling="no" frameborder="no"
src="{{ 'https://player.vimeo.com/video/' + url.split('https://vimeo.com/')[1] }}">
</iframe>
</div>
<a href="{{ url }}">Link</a>
{% elif 'tumblr.com' in url %}
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item"
src="{{ url }}" frameborder="0">
</iframe>
</div>
<a href="{{ url }}">Link</a>
{% else %}
<a href="{{ url }}">Link</a>
<br>
{% endif %}
{% endfor %}
<br>
<br>
<p class="text-muted"><strong>Tags:</strong></p>
{% for tag in post.tags.replace(' ', ' ').strip(',').split(' ') %}
<a class="btn btn-light" href="{{url_for('tag_posts', tag=tag)}}">{{tag.strip('#').strip(' ').lower() }}</a>
{% endfor %}
<br>
<form method="POST" action="" enctype="multipart/form-data">
{{ comment_form.hidden_tag() }}
<fieldset class="form-group">
<br>
<br>
<p class="text-muted"><strong>Add a comment:</strong></p>
<div class="form-group">
{% if comment_form.comment_string.errors %}
{{ comment_form.comment_string(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in comment_form.comment_string.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ comment_form.comment_string(class="form-control form-control-lg") }}
<!-- {{ add_comment(post_id=post.id) }}-->
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ comment_form.submit(class="btn btn-secondary") }}
</div>
</form>
<br>
<p class="text-muted mt-4"><strong>Street Cred: </strong>{{ get_upvote_count(post.id) }}</p>
<a class="btn btn-secondary mb-4" href="{{url_for('upvote', user_id=post.author.id, post_id=post.id)}}">Upvote</a>
</div>
</article>
{% endfor %}
{% for page_num in posts.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
{% if page_num %}
{% if posts.page == page_num %}
<a class="btn btn-secondary mb-4" href="{{ url_for('home', page=page_num) }}">{{ page_num }}</a>
{% else %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('home', page=page_num) }}">{{ page_num }}</a>
{% endif %}
{% else %}
...
{% endif %}
{% endfor %}
{% endblock content %}
{%extends“layout.html”%}
{%block content%}
{posts.items%}
发布日期:{{post.date\u poster.strftime(“%Y-%m-%d”)}
{{post.content}
{post.urls.split(“| |”)%%中的url为%
{%if'youtube.com'在url%}
{%elif'soundcloud.com'位于url%}
{%elif'spotify.com'位于url%}
{%elif'vimeo.com'在url%}
{%elif'tumblr.com'位于url%}
{%else%}
{%endif%}
{%endfor%}
标记:
{post.tags.replace('','').strip('',').split('')%%中的标记的%
{%endfor%}
{{comment_form.hidden_tag()}}
添加注释:
{%if comment\u form.comment\u string.errors%}
{{comment_form.comment_string(class=“form control form control lg is invalid”)}
{%表示注释\表单中的错误。注释\字符串。错误%}
{{error}}
{%endfor%}
{%else%}
{{comment_form.comment_string(class=“form control form control lg”)}
{%endif%}
{{comment_form.submit(class=“btn btn secondary”)}
街道信用:{{{get\u upvote\u count(post.id)}
{%endfor%}
{posts.iter_页面中的页数为%(左_边=1,右_边=1,左_边=1,右_边=2)%}
{%if page_num%}
{%if posts.page==page_num%}
{%else%}
{%endif%}
{%else%}
...
{%endif%}
{%endfor%}
{%endblock内容%}
有几个选项:
将post.id
作为参数或arg添加到url中,以下是arg方法:
将url添加到表单,并将post.id设置为参数:
<form method="POST" action="{{url_for('home', post_id=post.id)}}" enctype="multipart/form-data">
或
在表单中添加一个隐藏字段,并将其值设置为post.id
:
在表单中添加隐藏字段:
post_id = HiddenField()
您需要替换CSRF呈现(hidden_tag()
),以防止自动呈现post_id字段:
{{ comment_form.csrf_token }}
接下来,设置隐藏字段数据的值(此函数的回答分数):
最后,在路由中,(删除add_注释声明):
希望这有帮助,注意它没有经过测试
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...