问题
我正在尝试在Flask中使用AJAX显示图像文件。更具体地说,我想在单击按钮后显示图像,并在再次单击按钮时显示下一张图像(如幻灯片放映)。图像的文件名存储在我的数据库中。我查询数据库以获取当前用户的文件名列表,并将每个文件名与其余路径(将图像存储在磁盘上的路径)结合起来以显示图像。
到目前为止,我设法获得了当前用户的第一张图片。但是,我想不出一种方法来跟踪下一张要显示的图像。
我尝试使用全局变量作为应作为索引的计数器(file_counter
)。我想每次发出ajax请求以使下一个文件都增加file_counter 1,但计数器在后续调用时不会增加,也不会引发错误。
问题
我如何初始化全局变量(file_counter)以便将其值存储在多个调用中?此外,使用全局变量是否是这样做的正确方法?
HTML
<div id="ajax-field"></div>
<button class="btn btn-block" id="next-button"><p>Next Image!</p></button>
AJAX:
$('#next-button').click(function(){
$("#ajax-field").text("");
$.ajax({
url: "/get_data",
type: "POST",
success: function(resp){
$('#ajax-field').append(resp.data);
}
});
});
路由:
global filenames
global file_count
@app.route("/get_data", methods=['POST'])
def get_data():
try: # Is intended to fail on the first run in order for the global variables to be initialized. However it keeps failing on subsequent runs
display_img = filenames[file_count]
file_count +=1
except:
filenames = []
# current_user.uploads returns all file-objects of the current user
user_uploads = current_user.uploads
for file in user_uploads:
# file.filename returns the respective filename of the image
filenames.append(file.filename)
#filenames is now a list of filenames i.e. ['a.jpg','b.jpg','c.jpg'...]
display_img = filenames[0]
file_count = 1
path = "image_uploads/4_files/"+display_img
return jsonify({'data': render_template('ajax_template.html', mylist = path)})
ajax_template.html:
<ul>
{% block content %}
<li>
<img id="selected-image-ajax" src="{{url_for('static',filename=mylist)}}" class="img-thumbnail" style="display:block; margin:auto;"></img>
</li>
{% endblock content %}
</ul>
答案 0 :(得分:1)
正如@roganjosh所指出的,session
是跨多个请求存储信息的最佳方法。此解决方案展示了使用flask.session
存储计数器的照片显示实现:
import flask, random, string
app = flask.Flask(__name__)
app.secret_key = ''.join(random.choice(string.printable) for _ in range(20))
#to use flask.session, a secret key must be passed to the app instance
@app.route('/display_page', methods=['GET'])
def display_page():
'''function to return the HTML page to display the images'''
flask.session['count'] = 0
_files = [i.filename for i in current_user.uploads]
return flask.render_template('photo_display.html', photo = _files[0])
@app.route('/get_photo', methods=['GET'])
def get_photo():
_direction = flask.request.args.get('direction')
flask.session['count'] = flask.session['count'] + (1 if _direction == 'f' else - 1)
_files = [i.filename for i in current_user.uploads]
return flask.jsonify({'photo':_files[flask.session['count']], 'forward':str(flask.session['count']+1 < len(_files)), 'back':str(bool(flask.session['count']))})
当用户访问display_page
路由时,将调用/display_page
函数,并将计数设置为0
。 get_photo
绑定到/get_photo
路由,并且在发送ajax
请求时将被调用。
photo_display.html
:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div class='image_display'>
<img src="{{photo}}" id='photo_display' height="100" width="100">
<table>
<tr>
<td class='back'></td>
<td class='forward'><button id='go_forward' class='navigate'>Forward</button></td>
</tr>
</table>
</div>
</body>
<script>
$(document).ready(function(){
$('.image_display').on('click', '.navigate', function(){
var direction = 'b';
if ($(this).prop('id') === 'go_forward'){
direction = 'f';
}
$.ajax({
url: "/get_photo",
type: "get",
data: {direction: direction},
success: function(response) {
$('#photo_display').attr('src', response.photo);
if (response.back === "True"){
$('.back').html("<button id='go_back' class='navigate'>Back</button>")
}
else{
$('#go_back').remove();
}
if (response.forward === "True"){
$('.forward').html("<button id='go_forward' class='navigate'>Forward</button>")
}
else{
$('#go_forward').remove();
}
},
});
});
});
</script>
</html>
display_page.html
中的javascript与后端进行通信,并相应地更新img
标签src
。该脚本根据当前计数值添加或删除导航按钮。
演示:
为测试上述解决方案,我创建了一个图像文件夹来存储要显示的随机照片: