Python 3.x 让Flask更改HTML下拉列表中的选定值
我正在为家庭供暖控制系统编写一个原型前端,当用户从下拉框中选择房间和一周中的某一天时,我希望能够查询Redis数据库,检索当前设置的每小时温度,并使用它在温度下拉框中设置所选值。然后,用户可以更改一个或多个值并提交它们。我有提交和写的工作,只是想让我的头周围设置选定的 以下是HTML:Python 3.x 让Flask更改HTML下拉列表中的选定值,python-3.x,flask,Python 3.x,Flask,我正在为家庭供暖控制系统编写一个原型前端,当用户从下拉框中选择房间和一周中的某一天时,我希望能够查询Redis数据库,检索当前设置的每小时温度,并使用它在温度下拉框中设置所选值。然后,用户可以更改一个或多个值并提交它们。我有提交和写的工作,只是想让我的头周围设置选定的 以下是HTML: {% extends "bootstrap/base.html" %} {% block title %}Setting Room Temperatures{% endblock %} {% block navb
{% extends "bootstrap/base.html" %}
{% block title %}Setting Room Temperatures{% endblock %}
{% block navbar %}
<div class="navbar navbar-fixed-top">
<!-- ... -->
</div>
{% endblock %}
{% block content %}
</head>
<body>
<h1>Room temperature configuration</h1>
<form action="{{ url_for('heating_config_form')}}" method="post" class="form-inline">
<div class="form-group">
<label for="roomselect">Room:</label>
<select class="form-control" name="roomselect">
<option value="dining">Dining</option>
<option value="kitchen">Kitchen</option>
<option value="lounge">Lounge</option>
<option value="study">Study</option>
</select>
</div>
<br>
<br>
<div class="form-group">
<label for="dayselect">Day :</label>
<select class="form-control" name="dayselect">
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
</div>
<br>
<br>
<div class="form-group">
<label for="1AM">1AM :</label>
<select class="form-control" name="1AM">
<option value="5">5</option>
<option value="6">6</option>
</select>
<label for="2AM">2AM :</label>
<select class="form-control" name="2AM">
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
<br>
<br>
<button type="submit" value="submitted" name="update">Update temperature </button><br>
<br>
</form>
<br>
</body></html>
{% endblock %}<html><head>
我知道可能有更好的方法来实现这一点(WTForms?),但我想获得一个我理解的简单设置界面,这样我就可以在开发更好的前端的同时对系统进行原型化,因为我对Flask是新手,不希望整个加热系统依赖于我的能力:)
将温度添加到数据库工作正常,这是redis cli监视器的典型监视器输出
127.0.0.1:6379> monitor
OK
1482336847.287342 [0 127.0.0.1:34180] "HSET" "kitchen_tuesday" "1:00" "5"
1482336847.288042 [0 127.0.0.1:34180] "HSET" "kitchen_tuesday" "2:00" "5"
我在想,也许下面的上下文处理器会有所帮助
@app.context_processor
def utility_processor():
def retrieve_temp(sroom, sday, stime):
skey= (sroom + "_" + sday)
stemp = db.hget(skey, stime)
return stemp
return dict(retrieve_temp=retrieve_temp)
这将使函数retrieve_temp可用于所有模板-我想
然后,在渲染模板后,将使用默认的“房间和日期”在“时间”下拉列表中设置“选定”选项,然后每次移动“房间”和“日期”下拉列表时,同样的情况再次发生
因此,如果默认设置为“用餐”和“星期一”,则会检索凌晨1点和凌晨2点的温度,并将其设置为这些下拉列表中的“已选择”(次数更多,临时次数更多,为简洁起见,已将其删除)。如果房间和/或日期发生变化,它会再次发生。好的-所以在我给您提供解决问题的信息之前,我只想确定您的问题。您在评论中概述的作为备选方案的方法是实现此目标的最简单方法(例如,进行第一次选择的中间页面) 重要的是要记住,任何python或jinja2代码只执行一次。Jinja2使用一些逻辑来呈现HTML输出,然后Flask向浏览器响应一个静态HTML页面,因此您可以使用
context\u处理器
将特定逻辑传递给Jinja2,但一旦Flask呈现页面,任何交互都需要由javascript管理
看起来您正在使用引导,它包括jQuery
javascript库jQuery
非常棒(在我看来),因为它可以为您处理一些与DOM交互和操作方面的浏览器怪癖(例如,文档对象模型、javascript对HTML元素的表示)
因此,如果要动态填充第二个select,可以设计一些代码来异步(例如,无需再次发出HTTP请求或“重新加载”页面)将数据从浏览器发送到Flask端点,以获取所需的选项,然后更新前端。我给你举个例子:
HTML看起来是这样的(我只是在添加ID。假定for
标记引用的是ID字段,而不是名称,并且它还使javascript选择更容易):
哈…结果比我预期的要长一点,但这至少应该为你提供一个稻草人,让这样的功能发挥作用。Javascript无疑提供了更好的用户体验,但通过使用一系列填充静态页面的中间表单,您通常可以完成同样的任务。好的-在我向您提供解决问题的信息之前,我只想确定您的问题。您在评论中概述的作为备选方案的方法是实现此目标的最简单方法(例如,进行第一次选择的中间页面) 重要的是要记住,任何python或jinja2代码只执行一次。Jinja2使用一些逻辑来呈现HTML输出,然后Flask向浏览器响应一个静态HTML页面,因此您可以使用
context\u处理器
将特定逻辑传递给Jinja2,但一旦Flask呈现页面,任何交互都需要由javascript管理
看起来您正在使用引导,它包括jQuery
javascript库jQuery
非常棒(在我看来),因为它可以为您处理一些与DOM交互和操作方面的浏览器怪癖(例如,文档对象模型、javascript对HTML元素的表示)
因此,如果要动态填充第二个select,可以设计一些代码来异步(例如,无需再次发出HTTP请求或“重新加载”页面)将数据从浏览器发送到Flask端点,以获取所需的选项,然后更新前端。我给你举个例子:
HTML看起来是这样的(我只是在添加ID。假定for
标记引用的是ID字段,而不是名称,并且它还使javascript选择更容易):
哈…结果比我预期的要长一点,但这至少应该为你提供一个稻草人,让这样的功能发挥作用。Javascript无疑提供了更好的用户体验,但通常可以通过一系列填充静态页面的中间表单来完成同样的任务。为了澄清……您希望有一组选择框,其中第二个仅显示基于第一个选择的值?每次第一个框中的选择发生变化时,您都希望ping数据库以获得适当的选择来填充第二个选择?这是一个公平的摘要PJ。用户选择房间和日期后,将从该房间/日期组合的数据库中检索每个小时的相应温度设置,并填充相应的下拉选择。例如,如果用户选择Lounge和Tuesday,则数据库将查询当天每小时的所有当前温度设置,以便可以为thos设置选择
@app.context_processor
def utility_processor():
def retrieve_temp(sroom, sday, stime):
skey= (sroom + "_" + sday)
stemp = db.hget(skey, stime)
return stemp
return dict(retrieve_temp=retrieve_temp)
<div class="form-group">
<label for="roomselect">Room:</label>
<select class="form-control" name="roomselect" id="roomselect">
<option value="dining">Dining</option>
<option value="kitchen">Kitchen</option>
<option value="lounge">Lounge</option>
<option value="study">Study</option>
</select>
</div>
<div class="form-group">
<label for="dayselect">Day:</label>
<select class="form-control" name="dayselect" id="dayselect">
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
</div>
<div class="form-group">
<label for="1AM">1AM:</label>
<select class="form-control" name="1AM" id="1AM">
<option value="5">5</option>
<option value="6">6</option>
</select>
<label for="2AM">2AM:</label>
<select class="form-control" name="2AM" id="2AM" disabled>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
<script charset="utf-8" type="text/javascript">
// this is called a javascript closure. it also wont run the code until the page is finished loading
// and it protects the scope of your variables from other code you may later add to the page
$(function() {
var select_room = $('#roomselect'),
select_day = $('#dayselect'),
select_1am = $('#1am'),
select_2am = $('#2am');
select_room.on('change', function() {
// fires when room selection changes
getUpdatedSettings();
});
select_day.on('change', function() {
// fires when day selection changes
getUpdatedSettings();
});
function getUpdatedSettings() {
// data to send back to the server
var send = {
room: select_room.val(),
day: select_day.val()
};
// make the selections disabled while fetching new data
select_1am.attr('disabled', true);
select_2am.attr('disabled', true);
$.getJSON("/_get_updated_settings", send, function(response) {
// this send the room and the day select vals to the URL specified
// we will need to add a handler for this in Flask
// for the purpose of the example I am assuming the response will be
// a JSON object that has a dictionary of elements ("am_1" and "am_2")
// each of which is a list of values for the selects....
console.log(response); // good for QA!
// populate 1am
select_1am.empty();
$.each(response.am_1, function (index, value) {
select_1am.append(
$('<option>', {
value: value,
text: value
}, '</option>'))
});
// populate 2am
select_2am.empty();
$.each(response.am_2, function (index, value) {
select_2am.append(
$('<option>', {
value: value,
text: value
}, '</option>'))
});
// remove disabled now
select_1am.removeAttr('disabled');
select_2am.removeAttr('disabled');
});
}
});
</script>
from flask import jsonify
@app.route('/_get_updated_settings')
def get_updated_settings():
# good for debug, make sure args were sent
print request.args
day = request.args.get('day', 'default_if_none')
room = request.args.get('room', 'default_if_none')
key = (room + "_" + day)
output = {}
# I have no idea what this returns...just doing a list generator here assuming we get a list of values
output['am_1'] = [x for x in db.hget(skey, '1am')]
output['am_2'] = [x for x in db.hget(skey, '1am')]
return jsonify(output)