如何在Flask中使用AJAX遍历列表

时间:2018-11-10 21:38:53

标签: python jquery ajax flask

问题

我正在尝试在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>

1 个答案:

答案 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函数,并将计数设置为0get_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。该脚本根据当前计数值添加或删除导航按钮。


演示:

为测试上述解决方案,我创建了一个图像文件夹来存储要显示的随机照片:

enter image description here