我目前陷入了一个相当“重大”的问题,我会尽量清楚简明。 我正在使用Flask开发Python工具。它意味着是一个内联网。我的想法是我有一个客户页面。有它的名字,许多其他信息,以及一个庞大的清单。
信息已经写入输入字段,因此用户只需在那里编辑它们,按回车键,然后使用编辑的信息重新加载页面(通过通知,使用闪烁的消息和咆哮)。 大量的清单迫使我转移到使用AJAX的系统,因为我希望它在用户勾选框并在输入中输入内容时“实时”更新,而无需重新加载页面。
因此,我也将我对信息的基本输入切换为AJAX,以便重新加载法师。
我遇到过两个问题:
第一个涉及Flask的消息闪烁功能。我有一个更新数据库中客户端名称的方法,闪烁消息(成功或失败,取决于很多事情),然后再次显示该页面。为了避免页面重新加载,我正在使用AJAX管理表单提交。
问题是,我的python方法会闪烁消息。一旦我回到我的html页面(由于它是AJAX),它还没有重新加载,因此Jinja2的get_flashed_message函数没有返回任何内容,因为它尚未更新。因此,我无法检索那些闪烁的消息。
我怎样才能得到这些?我看到的唯一解决方案是摆脱任何flash的使用,并编写我自己的消息système,我将从方法返回,然后在javascript中处理。这看起来非常愚蠢,因为Flash是Flask的一个功能,它被AJAX“无用”了?我觉得我错过了什么。 (作为一个注释,到目前为止,我的闪存消息管理是在我的基本布局中进行的,它调用一个贯穿所有消息的模板并将其显示为咆哮通知)
第二个问题关注url_for。这是我的表单,用于编辑客户名称:
<form id="changeClientName" method="POST" action="{{ url_for('clients.edit_client_name', name=client.name) }}" style="display:inline !important;">
<input type="text" name="name" class="form-control" value="{{ client.name }}" >
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
</form>
如您所见,action属性使用url_for调用正确的方法来编辑客户端。我的方法如下:
@mod.route('/edit/<name>/', methods=['POST'])
def edit_client_name(name):
所以url路径是/ edit / the_client_name。因此,在编辑之后,如果我们要重新编辑此名称,则新URL为/ edit / the_new_client_name。 显然,一旦调用了该方法,我的AJAX必须更改此操作属性,将其替换为新URL(如果用户想要重新编辑名称而不更改页面/重新加载页面)。这是我的第二个问题。
新名称存储在javascript中。行动仍然是旧的网址。所以我必须使用新名称调用url_for。我发现绝对没有办法将Javascript变量传递给Jinja2。
我想要这个:
url_for('clients.edit_client_name', name=client.name)
成为这个:
url_for('clients.edit_client_name', name=my_javascript_variable_one_way_or_another)
我只需要调用修改表单属性的js函数,并使用这个新的url_for修改我的action属性。但是我发现没有办法做出这个简单的事情,即给Jinja2一个javascript变量,这对我来说似乎不太可能。
所以这是我的两个问题。如何使Flash与AJAX兼容?我怎样才能将javascript属性传递给Jinja2?
我真诚地希望为这两个“愚蠢”的问题找到解决方案。我能看到的唯一解决方案就是编写我自己的消息传递系统,它会破坏flash的目标,使得AJAX无用,这看起来很愚蠢,并且在我的模板中对URL进行硬编码,这完全违背了Flask制作的最初兴趣来自方法的URL独立,并且URL变化非常灵活。
感谢。
答案 0 :(得分:3)
我会抓住这个,但我不确定我完全理解这个问题:D。下面的代码没有经过测试,它更像是伪代码!
您的第一个问题是(如果我理解正确的话)您正在通过ajax进行部分更新,并希望在部分更新之后获取更新结果。您应该在每个ajax调用之后返回,而不是稍后获取更新结果 。因此,如果您的更新代码如下所示:
data = $('#my-form').serialize()
$.post(update_url, data, function (results) {
// Here you check results.
if (results.success) {
$('#update-div').message('Update Success')
} else {
$('#update-div').message('Update Failed: ' + results.error_msg)
}
})
然后您的更新路线将具有与此类似的代码:
from flask import jsonify
@app.route('/partialupdate/<int:userid>', methods=['POST'])
def partial_update(userid):
try:
# fetch the user, perform the updates and commit
return jsonify(success=1)
except Exception, e:
return jsonify(success=0, error_msg=str(e))
可以使用USERID而不是客户端名称修复涉及URL生成的第二个问题。 从不使用客户名称进行搜索以外的任何操作:D。在这种情况下使用用户ID。用户标识通常是数据库中特定用户的主键。如果您没有使用数据库,那么以某种方式生成您自己的用户ID并将其附加到用户 - 它应该是每个用户的唯一编号。使用用户ID意味着您始终可以使用“/ edituser / 1”等网址进行编辑。
答案 1 :(得分:1)
我也有这个要求。为了充实Paul Wand的答案,我就是这样做的(请注意,生成的标记是针对bootstrap 3的:
在模板中为flash消息添加一个空div:
<div id="flash"></div>
你的ajax电话:
$.post("/foo/bar", JSON.stringify({'calls': 'whatever'}), function(returnedData) {
$('#flash').append(flashMessage(JSON.parse(returnedData)));
});
并使用解析功能:
var flashMessage = function(data){
html = '';
for (i=0; i<data.length; i++) {
html += '<div class="alert alert-' + data[i]['type'] + '"><a href="#" class="close" data-dismiss="alert">×</a>' + data[i].message + '</div>';
}
return html;
};
在处理AJAX请求的路由中,只需返回一个类似于:
的JSON对象 [{'type': 'success', 'message': 'Here is a message'}]
其中&#39;类型&#39;是一个bootstrap 3状态类型,即。成功,信息,警告,危险。 dict包含在列表中,因此如果需要,您可以传递多个。
如果响应已经被jsonified,则不需要JSON.parse。在这种情况下,代码只是:
$('#flash').append(flashMessage(returnedData));
此外,如果您不需要多条Flash消息,只需更换“追加”即可。用&#39; html&#39;
答案 2 :(得分:0)
你可以写一个简单的javascript方法来取代烧瓶的功能&#39; flash&#39;通过了解flash_message.html的格式化方法。
function flash(message,category){
if (category == 'error'){
var icon='icon-exclamation-sign';
category='danger';
}
else if (category == 'success')
var icon='icon-ok-sign';
else
var icon='icon-info-sign';
$('<div class="alert alert-'+category+'"><i class="'+icon+'"></i> <a class="close" data-dismiss="alert">×</a>'+ message +'</div>').prependTo('#maincontent').hide().slideDown();
$.smoothScroll({
scrollElement: $('body'),
scrollTarget: '#mainContent'
});
}
url_for可能有点棘手,但可能。
答案 3 :(得分:0)
一个非常老的问题,但是我遇到了同样的问题,并且找到了一种通过ajax获取烧瓶闪烁的变通方法。基本上,我所做的是我创建了一条get_flashes路由,该路由返回flashes模板,并且正在通过jQuery的load函数使用该路由。 $('#msg-div').load('{{ url_for('main.get_flashes') }}'
get_flashes路线:
@main.route('get-flashes')
def get_flashes():
return render_template('_flashes.html')
_flashes.html(获取闪光的模板,请参见flask's docs中的更多信息)
{%- with messages = get_flashed_messages(with_categories=true) -%}
{% if messages %}
{% for category, message in messages %}
{% if category == 'error' %}
<div class="alert alert-danger alert-dismissable fade show msg" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% else %}
<div class="alert alert-{{ category }} alert-dismissable fade show msg" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endif %}
{% endfor %}
{% endif %}
{%- endwith %}