Как использовать AJAX во Flask для перебора списка - PullRequest
0 голосов
/ 11 ноября 2018

Задача

Я пытаюсь отобразить файлы изображений с помощью AJAX во Flask. В частности, я хочу отобразить изображение после нажатия кнопки и отобразить следующее изображение после повторного нажатия кнопки (например, слайд-шоу). Имена файлов изображений хранятся в моей базе данных. Я запрашиваю базу данных, чтобы получить список имен файлов для текущего пользователя и объединить каждое имя файла с остальной частью пути (путь к месту хранения изображений на диске), чтобы отобразить изображение.

Пока мне удается получить первое изображение текущего пользователя. Тем не менее, я не могу найти способ отслеживать, какое изображение будет показано следующим.

Я попытался использовать глобальную переменную в качестве счетчика (file_counter), который должен служить индексом. Я хочу увеличить file_counter на 1 каждый раз, когда делается ajax-запрос для получения следующего файла, но счетчик не увеличивается при последующих вызовах и не выдает ошибку.

Вопрос

Как мне нужно инициализировать глобальную переменную (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 голосов
/ 11 ноября 2018

Как отметил @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>

JavaScript в display_page.html связывается с бэкэндом и соответствующим образом обновляет тег img src. Сценарий добавляет или удаляет кнопки навигации в зависимости от текущего значения счетчика.


Демо-версия:

Чтобы проверить решение выше, я создал папку с изображениями для хранения случайных фотографий для отображения:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...