Задать вопрос
@Alexey_2057
Инженер

Связка Flask + jinja2. Почему происходит смещение строк при выводе на страницу?

Данные из скрипта на python выводятся на страницу с использованием flask и шаблонизатора jinja2.
Данные из трех ячеек массива выводятся в три строки и обновляются в браузере раз в 3 сек.
Код на python
#!/usr/bin/env python
# main script of page
import random
import os, sys 
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/<name>', methods= ['GET'])
def main(name=None):  # этот код выполняется сразу при первой загрузке страницы в браузере, а также переодически вызывается с нее по таймауту

# заполнение массива array_main:
   array_main = [] # пустой список, его размер не определен
   random_N1 = round(random.random(), 3) # округление до 3 знака после запятой			
   array_main.append(random_N1)
   random_N2 = round(random.random(), 3) # округление до 3 знака после запятой			
   array_main.append(random_N2)  
   random_N3 = round(random.random(), 3) # округление до 3 знака после запятой			
   array_main.append(random_N3)  
 
   print ("array_main[0]=", array_main[0])
   print ("array_main[1]=", array_main[1])
   print ("array_main[2]=", array_main[2])
  
   array_main = {'array_main': array_main}
   
   return render_template("index.html", title='Test Array', 
       array_main=array_main)
####################################################################################################				
   
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000, debug=True)


Код HTML запроса:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=CP1251">

<!-- Подключение библиотеки jQuery: -->
	<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>	
	
<script type="text/javascript">	

//** Эта функция выполняется переодически, запрашиваются данные из скрипта index.py
setInterval(Test_OutputArray, 3000);  // устанавливает время между запусками функции Test_OutputArray()

// Функция Test_OutputArray выводит данные из массива array_main:
// один раз при первой загрузке страницы!
// затем переодически через 3 сек.
function Test_OutputArray ()
   {
		$('#array_main').load(document.URL +  ' #array_main');
   }

    </script>
</head>

<body>
<span style="color: green;" >Test output Array (version 1) </span><br>

	<hr>
	<div id="array_main">Вывод первого элемента массива array_main[0]: {{ array_main.array_main[0]}}</div>  
	<div id='array_main'>Вывод второго элемента массива array_main[1]: {{ array_main.array_main[1]}}</div>  
	<div id='array_main'>Вывод третьего элемента массива array_main[2]: {{ array_main.array_main[2]}}</div>  	
	<hr>

</body>
</html>


При первой загрузке страницы в браузере все нормально: выводятся три строки с данными из трех ячеек массива, см. скрин sceen_1.jpg
Но потом при обновлении страницы через 3 сек. ранее выведенные данные из второй и третьей строк СМЕЩАЮТСЯ (переносятся) вниз в четвертую и пятую строку соответственно, и далее вывод осуществляется в первые три строки, см. скрин sceen_2.jpg
Как избавится от вывода в пять строк, чтобы данные из трех ячеек выводились только в три строки и не было смещения строк.
Версии:
Python 3.13.5
Flask 3.1.1
Проверено в Linux и Windows
Спасибо.

7632281d11cc15c31a045ef974002dfb.jpg
60dfc5ded195e399e94e83c4df9004a0.jpg
  • Вопрос задан
  • 122 просмотра
Подписаться 2 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Фаст Лейн
    Веб-разработка на Flask + AI-прототипирование
    1 неделя
    Далее
  • Академия Эдюсон
    Python-разработчик + ИИ
    9 месяцев
    Далее
  • Нетология
    Python-разработчик: расширенный курс + нейросети
    12 месяцев
    Далее
Решения вопроса 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
В HTML не должно быть нескольких элементов с одинаковым id.
У вас три элемента div с id="array_main".
Обращение $('#array_main') выбирает только первый из них.
Посмотрите структуру страницы, там, скорее всего, получается
<div id="array_main">
    <div id="array_main">Вывод первого элемента массива array_main[0]: {{ array_main.array_main[0]}}</div>  
    <div id='array_main'>Вывод второго элемента массива array_main[1]: {{ array_main.array_main[1]}}</div>  
    <div id='array_main'>Вывод третьего элемента массива array_main[2]: {{ array_main.array_main[2]}}</div>
</div>
<div id='array_main'>Вывод второго элемента массива array_main[1]: {{ array_main.array_main[1]}}</div>  
<div id='array_main'>Вывод третьего элемента массива array_main[2]: {{ array_main.array_main[2]}}</div>

Вам надо оставить id только у того div'а, содержимое которого должно изменяться.
Ответ написан
Oleca
@Oleca
Бизнес-аналитик, предприниматель и Middle Backend
Проблема возникает из-за дублирования одинаковых id="array_main" на странице и специфики работы метода $.load().По спецификации HTML идентификаторы должны быть уникальными. Метод $('#array_main').load(URL + ' #array_main') находит на странице только первый элемент с этим ID и вставляет внутрь него всё, что нашел под селектором #array_main в пришедшем AJAX-ответе (а там приходят все 3 строки). В итоге первая строка раздувается, а старые вторая и третья строки смещаются вниз.Решение проблемы без изменения Python-кода:Нужно объединить выводимые строки в один общий родительский контейнер с уникальным ID, а внутренним элементам дать уникальные классы или идентификаторы.1.
Замените HTML-разметку в шаблоне на следующую:




Вывод первого элемента массива array_main[0]: {{ array_main.array_main[0] }}
Вывод второго элемента массива array_main[1]: {{ array_main.array_main[1] }}
Вывод третьего элемента массива array_main[2]: {{ array_main.array_main[2] }}



2. Измените скрипт JavaScript:Нацельте метод .load() на обновление родительского контейнера целиком:

function Test_OutputArray() {
// Загружаем только содержимое контейнера и обновляем его на странице
$('#array_main_container').load(document.URL + ' #array_main_container > *');
}

Конструкция > * указывает jQuery взять именно внутреннее содержимое контейнера из ответа сервера, чтобы избежать бесконечного вложения элементов друг в друга.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
opium
@opium
Просто люблю качественно работать
jinja2 и ajax тут не альтернативы: твой .load() и есть ajax, просто расточительный. Каждые 3 сек он тянет всю страницу, Flask рендерит шаблон целиком, а jQuery вырезает из неё один блок.
Для датчиков лучше отдельный роут, который отдаёт только данные (return jsonify(values)), и fetch('/api/sensors') по setInterval с обновлением textContent. Jinja оставь для первой отрисовки.
Если нужно чаще раза в секунду или пуш по событию, глянь SSE, для односторонней телеметрии он проще вебсокета. Сами датчики не опрашивай внутри запроса: отдельный поток складывает последние значения в память или Redis, роут отдаёт готовое.
Ответ написан
@Alexey_2057 Автор вопроса
Инженер
Olesya Dekhand, спасибо за ответ. Я сделал, как Вы посоветовали:

<! 24.09.2026 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=CP1251">
<!-- Подключение библиотеки jQuery: -->
	<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>	
	
<script type="text/javascript">	

//** Эта функция выполняется переодически, запрашиваются данные из скрипта index.py
setInterval(Test_OutputArray, 3000);  // устанавливает время между запусками функции Test_OutputArray()

// Функция Test_OutputArray выводит данные из массива array_main:
// один раз при первой загрузке страницы!
// затем переодически через 3 сек.
function Test_OutputArray ()
   {
	//	$('#array_main').load(document.URL +  ' #array_main');
	$('#array_main_container').load(document.URL + ' #array_main_container > *');
   }

    </script>
</head>

<body>
<span style="color: green;" >Test output Array (version 1.1) </span><br>

<hr>
Вывод первого элемента массива array_main[0]: {{ array_main.array_main[0] }} <BR>
Вывод второго элемента массива array_main[1]: {{ array_main.array_main[1] }} <BR>
Вывод третьего элемента массива array_main[2]: {{ array_main.array_main[2] }} <BR>
<hr>
 
</body>
</html>


Но страница не обновляется автоматически.
Вы пишите "Решение проблемы БЕЗ ИЗМЕНЕНИЯ Python-кода", - это правильно?
Как тогда происходит загрузка контейнера array_main_container?
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы