Flask应用正在正确运行功能,但未呈现模板。

huangapple go评论65阅读模式
英文:

Flask app is running correct function, but not rendering template

问题

以下是代码的中文翻译:

我有一个使用模板的Flask应用程序我试图通过JavaScript在用户点击按钮时通过POST发送多个项目当我将数据发布到/confirm时打印语句执行但render_template函数不渲染任何内容我的Web浏览器停留在/likes页面

这是web_interface.py

#!/bin/python3

from flask import Flask, render_template, request, url_for, redirect
import twitter as twitter
from dataclasses import dataclass
import json

app = Flask(__name)

form_data = {}
tweet_data = {}

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/likes", methods=['POST','GET'])
def likes():
    if request.method == 'POST':
        tweet_url = request.form['inputTweetURL1']
        liking_user_list = twitter.liking_users_lookup_by_url(tweet_url)
        return render_template("likes.html", liking_user_list=liking_user_list)
    else:
        return render_template("likes.html")

@app.route('/confirm', methods=['POST'])
def confirm():
    block_list = json.loads(request.data.decode())['data']
    print(block_list)
    return render_template("confirm.html", block_list=block_list)

app.run(host="0.0.0.0", port=80)

以下是模板的中文翻译:

{% extends 'base.html' %}

{% block content %}

<form method='POST'>
    <div class="mb-3">
        <label for="inputTweetURL1" class="form-label">Tweet URL</label>
        <input type="text" class="form-control" name="inputTweetURL1" id="inputTweetURL1"
            aria-describedby="inputTweetURL1Help">
    </div>
    <button type="submit" class="btn btn-primary">提交</button>
</form>

<div class="scrollme">
    <table class="table table-striped">
        <!-- 表头 -->
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">姓名</th>
                <th scope="col">用户ID</th>
                <th scope="col">个人资料网址</th>
                <th scope="col">粉丝数量</th>
                <th scope="col">验证状态</th>
                <th scope="col">屏蔽用户</th>
            </tr>
        </thead>
        <!-- 表格主体 -->
        <tbody class="table-group-divider">
            <!-- Jinja模板的循环逻辑 -->
            {% for user_data in liking_user_list %}
            <!-- 表格行 -->
            <tr>
                <th scope="row">1</th>
                <td>{{user_data['name']}}</td>
                <td>{{user_data['id']}}</td>
                <td><a href="https://twitter.com/{{ user_data.username }}">https://twitter.com/{{ user_data['username'] }}</a></td>
                <td>{{user_data['public_metrics']['followers_count']}}</td>
                <td>{{user_data['verified']}}</td>

                <td><a><button type="button" class="btn btn-primary toggle-button">屏蔽</button></a></td>
            {% endfor %}
            </tr>
        </tbody>
    </table>
    <button type="submit" id="danger-report" class="btn btn-primary">提交</button>
    <input type="hidden" name="hiddenInput" id="hiddenInput">
</div>

<script>
    $(document).ready(function () {
        // 为ID为"danger-report"的按钮添加点击事件监听器
        $('#danger-report').click(function () {
            // 获取所有具有btn-danger类的按钮
            var dangerButtons = $('.btn-danger');

            // 过滤包含危险按钮的行
            var dangerRows = dangerButtons.parents('tr');

            // 定义一个空列表来存储<td>元素的内容
            var tdContents = [];

            // 将危险行的数量和它们的内容记录到控制台
            dangerRows.each(function () {
                var name = $(this).find('td:eq(0)').text(); // 获取行中第一个<td>元素的文本内容
                var id = $(this).find('td:eq(1)').text(); // 更改为要记录的<td>元素的索引
                var url = $(this).find('td:eq(2)').text(); // 更改为要记录的<td>元素的索引
                var followers = $(this).find('td:eq(3)').text(); // 更改为要记录的<td>元素的索引
                var verified = $(this).find('td:eq(4)').text(); // 更改为要记录的<td>元素的索引

                var item = { "name": name, "id": id, "url": url, "followers": followers, "verified": verified }

                tdContents.push(JSON.stringify(item));
            });

            // 将tdContents数组的内容使用逗号拼接起来
            var dataToSend = tdContents.join(',');

            var r = new XMLHttpRequest();
            r.open("POST", "http://127.0.0.1/confirm", true);
            r.onreadystatechange = function () {
                if (r.readyState != 4 || r.status != 200) return;
                console.log("已发送");
            };

            r.send(JSON.stringify({ "data": dataToSend }));
        });
    });
</script>
{% endblock %}

请注意,以上是代码和模板的中文翻译,不包括原始问题的回答部分。如果您有其他问题或需要进一步的帮助,请随时告诉我。

英文:

I have a flask app with a template. I am attempting to send via post several items collected by javascript when the user clicks a button. When I post my data to /confirm, the print statement executes, but the render_template function does not render anything, my web browser stays on the /likes page.

Here is the web_interface.py:

#!/bin/python3
from flask import Flask, render_template, request, url_for, redirect
import twitter as twitter
from dataclasses import dataclass
import json
app = Flask(__name__)
form_data = {}
tweet_data = {}
@app.route(&quot;/&quot;)
def index():
return render_template(&quot;index.html&quot;)
@app.route(&quot;/likes&quot;, methods=[&#39;POST&#39;,&#39;GET&#39;])
def likes():
if request.method == &#39;POST&#39;:
tweet_url = request.form[&#39;inputTweetURL1&#39;]
liking_user_list = twitter.liking_users_lookup_by_url(tweet_url)
return render_template(&quot;likes.html&quot;, liking_user_list=liking_user_list)
else:
return render_template(&quot;likes.html&quot;)
@app.route(&#39;/confirm&#39;, methods=[&#39;POST&#39;])
def confirm():
#block_list = json.loads(request.data.decode())[&quot;data&quot;]
# print(&quot;Print the data: {}&quot;.format(foo))
block_list = json.loads(request.data.decode())[&#39;data&#39;]
print(block_list)
return render_template(&quot;confirm.html&quot;, block_list=block_list)
app.run(host=&quot;0.0.0.0&quot;, port=80)

And here is the template:

{% extends &#39;base.html&#39; %}
{% block content %}
&lt;form method=&#39;POST&#39;&gt;
&lt;div class=&quot;mb-3&quot;&gt;
&lt;label for=&quot;inputTweetURL1&quot; class=&quot;form-label&quot;&gt;Tweet URL&lt;/label&gt;
&lt;input type=&quot;text&quot; class=&quot;form-control&quot; name=&quot;inputTweetURL1&quot; id=&quot;inputTweetURL1&quot;
aria-describedby=&quot;inputTweetURL1Help&quot;&gt;
&lt;/div&gt;
&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;
&lt;div class=&quot;scrollme&quot;&gt;
&lt;table class=&quot;table table-striped&quot;&gt;
&lt;!-- Table headers --&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope=&quot;col&quot;&gt;#&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Name&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;User ID&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Profile URL&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Follower Count&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Verified Status&lt;/th&gt;
&lt;th scope=&quot;col&quot;&gt;Block User&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;!-- Table body --&gt;
&lt;tbody class=&quot;table-group-divider&quot;&gt;
&lt;!-- For loop logic of jinja template --&gt;
{%for user_data in liking_user_list%}
&lt;!-- Table rows --&gt;
&lt;tr&gt;
&lt;th scope=&quot;row&quot;&gt;1&lt;/th&gt;
&lt;td&gt;{{user_data[&#39;name&#39;]}}&lt;/td&gt;
&lt;td&gt;{{user_data[&#39;id&#39;]}}&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://twitter.com/{{ user_data.username }}&quot;&gt;https://twitter.com/{{ user_data[&#39;username&#39;]
}}&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;{{user_data[&#39;public_metrics&#39;][&#39;followers_count&#39;]}}&lt;/td&gt;
&lt;td&gt;{{user_data[&#39;verified&#39;]}}&lt;/td&gt;
&lt;td&gt;&lt;a&gt;&lt;button type=&quot;button&quot; class=&quot;btn btn-primary toggle-button&quot;&gt;Block&lt;/button&gt;&lt;/a&gt;&lt;/td&gt;
{%endfor%}
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;button type=&quot;submit&quot; id=&quot;danger-report&quot; class=&quot;btn btn-primary&quot;&gt;Submit&lt;/button&gt;
&lt;input type=&quot;hidden&quot; name=&quot;hiddenInput&quot; id=&quot;hiddenInput&quot;&gt;
&lt;/div&gt;
&lt;script&gt;
$(document).ready(function () {
// Add click event listener to a button with an ID of &quot;danger-report&quot;
$(&#39;#danger-report&#39;).click(function () {
// Get all the buttons with the btn-danger class
var dangerButtons = $(&#39;.btn-danger&#39;);
// Filter out the rows that contain the danger buttons
var dangerRows = dangerButtons.parents(&#39;tr&#39;);
// Define an empty list to store the contents of the &lt;td&gt; elements
var tdContents = [];
// Log the number of danger rows and their contents to the console
dangerRows.each(function () {
var name = $(this).find(&#39;td:eq(0)&#39;).text(); // Get the text content of the first &lt;td&gt; element in the row
var id = $(this).find(&#39;td:eq(1)&#39;).text(); // Change &#39;1&#39; to the index of the &lt;td&gt; you want to log
var url = $(this).find(&#39;td:eq(2)&#39;).text(); // Change &#39;1&#39; to the index of the &lt;td&gt; you want to log
var followers = $(this).find(&#39;td:eq(3)&#39;).text(); // Change &#39;1&#39; to the index of the &lt;td&gt; you want to log
var verified = $(this).find(&#39;td:eq(4)&#39;).text(); // Change &#39;1&#39; to the index of the &lt;td&gt; you want to log
var item = { &quot;name&quot;: name, &quot;id&quot;: id, &quot;url&quot;: url, &quot;followers&quot;: followers, &quot;verified&quot;: verified }
tdContents.push(JSON.stringify(item));
});
//console.log(tdContents)
// Join the contents of the tdContents array with commas
var dataToSend = tdContents.join(&#39;,&#39;);
var r = new XMLHttpRequest();
r.open(&quot;POST&quot;, &quot;http://127.0.0.1/confirm&quot;, true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
//alert(&quot;Success: &quot; + r.responseText);
console.log(&quot;Sent&quot;);
};
// Send data in below way from JS
r.send(JSON.stringify({ &quot;data&quot;: dataToSend }));
});
});
&lt;/script&gt;
{% endblock %}

I can't figure out why when posting r.send the template isn't rendered. Any ideas?

UPDATE:
Here is the updated routing:

@app.route(&#39;/confirm&#39;, methods=[&#39;POST&#39;,&#39;GET&#39;])
def confirm():
if request.method == &#39;POST&#39;:
#block_list = json.loads(request.data.decode())[&quot;data&quot;]
# print(&quot;Print the data: {}&quot;.format(foo))
block_list = json.loads(request.data.decode())[&#39;data&#39;]
#print(block_list)
print(&#39;youre posting, it worked&#39;)
return render_template(&quot;confirm.html&quot;, block_list=block_list)
else: 
block_list = json.loads(request.data.decode())[&#39;data&#39;]
print(&#39;youre gettin&#39;)
return render_template(&#39;confirm.html&#39;, block_list=block_list)

And here is the function where the POST request is sent. Is this where I need to do the redirecting?

    var r = new XMLHttpRequest();
r.open(&quot;POST&quot;, &quot;http://127.0.0.1/confirm&quot;, true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
//alert(&quot;Success: &quot; + r.responseText);
console.log(&quot;Sent&quot;);
//window.location.href = &quot;/confirm&quot;; // Redirect to /confirm
};
// Send data in below way from JS
r.send(JSON.stringify({ &quot;data&quot;: dataToSend }));
window.location.href = &quot;/confirm&quot;;

答案1

得分: 1

你可以通过将所选行的ID发送到/confirm端点来简化逻辑。然后,让端点确定ID代表的数据并为您呈现它。

@app.route('/confirm', methods=['GET'])
def confirm():
  args = request.args
  ids = args.get('ids')
  id_list = ids.split(',')
  return render_template('confirm.html', id_list=id_list)
英文:

You can simplify the logic by sending the ids of the selected rows to the /confirm endpoint. Then let the endpoint figure our what data the ids represent and render it for you.

@app.route(&#39;/confirm&#39;, methods=[&#39;GET&#39;])
def confirm():
args = request.args
ids = args.get(&#39;ids&#39;)
id_list = ids.split(&#39;,&#39;)
return render_template(&#39;confirm.html&#39;, id_list=id_list)

huangapple
  • 本文由 发表于 2023年2月27日 06:20:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定