如何在不重新加载页面的情况下更改 Flask 应用程序和使用的数据库?

问题描述 投票:0回答:1

我想实现某种无需重新加载页面即可更改网页和数据库的方法。

大家好,我正在创建一个能够执行以下操作的烧瓶应用程序:人们能够提出问题,然后对这些问题发表评论。一个人如果有帐户就可以提出问题,如果他们是发布问题的人,他们可以删除问题。有问题可以举报。所有这些也可以通过评论来完成。我已经按照我想要的方式工作了。

我这样做的问题是页面必须重新加载才能发生更改。这是 flask 路由和 html 提交表单。因此,如果有人发表了新评论,整个页面都会重新加载,如果他们想继续查看评论,则必须返回到他们所在的位置。

下面是如何将信息发送到flask路由,从而重新加载页面。这是一个 html 文件,显示网页上的所有信息。

{% for item in htmlQuestion %}
      <div class="accordion accordion-flush" id="accordionPanel-Questions">
        <div class="accordion-item">

          <!-- This is where the three dots show up for the post options -->
          <div id = "test-cont">
            <div id="container">
              <div id="menu-wrap">
                <input type="checkbox" class="toggler" />
                <div class="dots">
                  <div></div>
                </div>
                <div class="menu">
                  
                    <ul class = "post-options">
                      {% if item.posterName == currentUser%}
                        
                          <form class = "input-group" action = "/deletePost/{{item._id}}/{{item.csClass}}" method = "post" id = "delete-button-form"> 
                            <input type = "submit" name = "submit-button" value = "Delete Post" id = "delete-post-box" />
                          </form>
                        
                      {% endif %}
                      <form class = "input-group" action = "/reportPost/{{item._id}}/{{item.csClass}}" method = "post"> 
                        <input type = "submit" name = "submit-button" value = "Report Post" id = "report-post-box" />
                      </form>
                    </ul>

                </div>
              </div>
            </div>
          </div>

          <!-- The rest of the info in the post header -->

          <h2 class="accordion-header" id = "accordionPanel-Questions">
            <button id = "post-button-info" class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#panelsStayOpen-{{item._id}}" aria-expanded="false" aria-controls="panelsStayOpen-{{item._id}}">
              <div class = "question-info">
                <p id = "question-info">Class: {{item.csClass}} Posted by: {{item.posterName}} </p><!-- .csCSClass, posterName, and ._id are all attributes in the db model -->
                <br>
                <div class = "question-header">
                  <p> <strong>Question: </strong> {{item.userQuestion}} </p>
                  <br>
                </div>
              </div>
            </button>
          </h2>
          <div id="panelsStayOpen-{{item._id}}" class="accordion-collapse collapse" aria-labelledby="panelsStayOpen-headingOne">
            <div class="accordion-body">
                <p><strong>Comments: </strong></p>
                <br>

                <!-- TODO: changee the buttons so that they are '...' that give you the option to delete or report -->

                {% for comment in htmlResponses %}
                    {% if comment.post_id == item._id %}   
                      <div class = "comment-box">
                        <div class="dropdown-center">
                          <button type = "button" class = "btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" id = "options-comment"> ... </button>
                          <ul class = "dropdown-menu"> 
                            <form class = "del-comm" action = "/reportComment/{{comment.id}}/{{item.csClass}}" method = "post"> 
                              <input type = "submit" name = "submit-button" value = "Report Comment" id = "delete-comment-box" />
                            </form>
                            {% if comment.posterUsername == currentUser %}
                              <!-- Kind of like the last if checking if currentUser is the same as the comment poster. If they are they can delete the post and if not
                                    they are not given the option to delete  -->
                              
                                <form class = "del-comm" action = "/deleteComment/{{comment.id}}/{{item.csClass}}" method = "post"> 
                                  <input type = "submit" name = "submit-button" value = "Delete Comment" id = "delete-comment-box" />
                                </form>
                              
                              {% endif %}
                          </ul>
                        </div>
                          <p>{{comment.content}}</p>
                          <p> Comment By: {{comment.posterUsername}}</p> 
                      </div>  
                      <br>
                    {% endif %}
                    
                {% endfor %}
                <form class = "input-group" action = "/createComment/{{item._id}}/{{item.csClass}}" method = "post"> 
                        <input type = "text" placeholder = "enter response..." id = "response-box" name = "userResponse" size = 40/> <!-- name is used in the python stuff and id is used in the css stuff -->
                        <input type = "submit" name = "submit-button" value = "Post Response" id = "create-comment-box" onkeydown = "return event.key != 'Enter';" />
                </form>
            </div>
          </div>
        </div>
      </div>
    {% endfor %}

以下是用来做改动的flask路由。需要注意的一件事是,问题是按类型分组的。对于测试,只有 CS-1、CS-2、... 和一般。

# allows the user that posted a post to delete and when a post is deleted, all comments associated with it are also deleted
# getting sent here is dependent on the html if 

@qANDa.route("/deletePost/<post_id>/<csClass>", methods = ["POST"])
def deletePost(post_id, csClass):
    post = Questions.query.filter_by(_id = post_id).delete()
    db.session.commit()
    question = Comment.query.filter_by(post_id = post_id).delete()
    db.session.commit()
    if csClass == "General":
        return redirect(url_for("qANDa.viewQ"))
    elif csClass == "CS-1":
        return redirect(url_for("qANDa.viewCS1"))
    elif csClass == "CS-2":
        return redirect(url_for("qANDa.viewCS2"))
    elif csClass == "CS-3":
        return redirect(url_for("qANDa.viewCS3"))
    elif csClass == "CS-4":
        return redirect(url_for("qANDa.viewCS4"))
    else:
        return redirect(url_for("qANDa.viewQ"))

# deletes a single comment in a post if the deleter is also the comment poster
# this is the same as the del post where it is called from html

@qANDa.route("/deleteComment/<post_id>/<csClass>", methods = ["POST"])
def deleteComment(post_id, csClass):
    post = Comment.query.filter_by(id = post_id).delete()
    db.session.commit()
    if csClass == "General":
        return redirect(url_for("qANDa.viewQ"))
    elif csClass == "CS-1":
        return redirect(url_for("qANDa.viewCS1"))
    elif csClass == "CS-2":
        return redirect(url_for("qANDa.viewCS2"))
    elif csClass == "CS-3":
        return redirect(url_for("qANDa.viewCS3"))
    elif csClass == "CS-4":
        return redirect(url_for("qANDa.viewCS4"))
    else:
        return redirect(url_for("qANDa.viewQ"))

以下是查看问题和重新加载更改的路线。还有更多,但除了 filter_by 正在寻找的内容之外,它们都是一样的。 (一般、CS-1 等)

# just lets user view all post <! --- Changes later so that the post are organized by class rather than having them all in one place --- !>
@qANDa.route("/viewQuestions", methods = ["POST", "GET"])
def viewQ():
    q = Questions.query.filter_by(csClass = "General")
    if current_user.is_authenticated:
        if q.count() == 0:
                return render_template("emptyClass.html")
        else:
            return render_template("viewQuestions.html", htmlQuestion = q, htmlResponses = Comment.query.all(), currentUser = current_user.username)
    else:
        if q.count() == 0:
            return render_template("emptyClass.html")
        return render_template("viewQuestions.html", htmlQuestion = q, htmlResponses = Comment.query.all(), currentUser = "notSignedIn")

我理解这是如何工作的方式如下:

提交按钮,一旦点击,发送信息到烧瓶路线。

根据单击哪个按钮,评论/问题将从 SqlAlchemy 数据库中删除。

一旦删除,将调用删除任何类型问题的网址。显示信息和发生的变化。

我希望能够进行更改而不是重新加载页面,但我不知道该怎么做。我研究过 Ajax 和 htmx,但我真的不明白发生了什么。

有谁知道我应该去哪里以及我可以找到什么资源来解决这个问题?如果有任何问题

flask sqlalchemy flask-sqlalchemy
1个回答
0
投票

你在正确的道路上。 HTMX(正如您所提到的)将是实现此处目标的最简单方法。他们的网站上有很多示例来解释其工作原理的前端部分。例如制作一个删除元素等的按钮

基本上,您想为每种类型的操作创建一个路由(例如,一个用于删除的路由和一个用于编辑的路由),您还可以在其中发送有关您要处理哪个项目的信息。这可能是像

/delete/<item_id>
这样的路线。你想让 htmx 在点击按钮等时调用这些 urls (hx-get)

在这些路由中的每一个中,您都创建用于删除或更改数据库中条目的逻辑,然后将响应(例如“项目已被删除”)返回到 HTMX 将集成到 html 中的前端。

© www.soinside.com 2019 - 2024. All rights reserved.