zvepb
@zvepb

Не могу разобраться с web socket и ajax. Как все таки обновлять данные на Flask сервере без F5?

Привет Хабр !

Не могу до конца разобраться с этим вопросом. Не нашел никак нужные примеры, а по документации сделать пока не получается. Хочу здесь привести свой пример, и попросить помощи, как можно реализовать то что мне нужно. Самостоятельно никак не дойдет до меня, как это работает :D

Мой пример:

На сервере по расписанию выполняются .py скрипты. Результат их выполнения пишется в PostgreSQL в простую таблицу вида (id, result) - больше никакой информации в принципе не нужно, скрипт знает, что ему писать. Так вот, на фласк у меня вот такой код :

@app.route("/atol", methods=["GET", "POST"])
def atollog():
    global atol_flag
    atolbuff = Atol.query.order_by(Atol.id.asc()).all()
    return render_template('atol.html', atolbuff=atolbuff)


А в html я выбираю данные в таблицу :
<div class='once'>
	<table>
		<thead>
			<tr>
				<th>Логи кассы</th>
			</tr>
		</thead>
		<tbody>
		{% for logs in atolbuff %}
			<tr>
				<td>{{logs}}</td>
			</tr>
		{% endfor %}
		</tbody>
	</table>
</div>


Все работает через F5. Нажал Ф5 - данные обновил. Как мне связать тэги html, с моей функцией def atollog() я так и не пойму. Если кто то сможет, подтолкните на реализацию на данном простом примере. Я пока понимаю только то, что надо добавить ajax, джава скрипт в котором через коннект к бэкэнду связать тэг html с информацией из БД, но чтобы я не пробовал, socket.io или js, пока все мимо %)
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
SoreMix
@SoreMix Куратор тега Python
yellow
Подключаем jquery к html:
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>


Вообще, вариантов конечно много, но в общем случае можно сделать так:
Разбить таблицу и основной файл на два html дока

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
    <div class='once'>
  <table id="logs">
      {% include 'table.html' %}
  </table>
</div>

<script>

function updateTable() {
    $.ajax({
        url: "/",
        type: "get",
        success: function(response) {
            $("#logs").html(response);
        }
    });
};

setInterval(updateTable, 3000);
</script>
</body>
</html>


table.html
<thead>
  <tr>
    <th>Логи кассы</th>
  </tr>
</thead>
<tbody>
  {% for logs in atolbuff %}
    <tr>
      <td>{{logs}}</td>
    </tr>
  {% endfor %}
</tbody>


В html файле каждые 3000 м.сек (3 сек) отправляется get на /. Опять же, можно сделать отдельный эндпоинт, можно слать POST, можно это, можно то и тд.

В самомо боте проверяем что за запрос пришел, подобные запросы называются XHR. Если нам пришел XHR запрос (из ajax каждые 3 сек), то рендерим нашу таблицу и возвращаем её. Если это был обычный запрос, то рендерим index.
@app.route("/")
def hello_world():
    
    atolbuff = [random.choices(string.ascii_lowercase, k=10) for x in range(3)]
    
    if request.is_xhr:
        return render_template('table.html', atolbuff=atolbuff)
    
    else:
        return render_template('index.html', atolbuff=atolbuff)


В JS'e получаем результат функции render_template('table.html') и через jQuery заменяем им html элемента с id logs (таблица в моем случае):

function updateTable() {
    $.ajax({
        url: "/",
        type: "get",
        success: function(response) {
            $("#logs").html(response);
        }
    });
};


+ пару импортов
from flask import Flask, render_template, request
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы