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。因此,当表单被验证时,注释将应用于所有帖子,而不仅仅是添加注释的帖子

问题:我如何从Jinja
forloop
获取
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...