Python 使用Jinja循环浏览2D列表
为了简单起见,我将提出一个与我目前的情况相当的假设。我使用Flask作为后端为前端呈现Jinja模板。假设我有一个类列表,每个类都是一个学生列表(带有属性的Python类/节点和all)。我希望一次渲染一个“学生类”,并使用按钮循环到下一组学生。下面是一个示例,展示了它的外观: app.pyPython 使用Jinja循环浏览2D列表,python,ajax,flask,jinja2,Python,Ajax,Flask,Jinja2,为了简单起见,我将提出一个与我目前的情况相当的假设。我使用Flask作为后端为前端呈现Jinja模板。假设我有一个类列表,每个类都是一个学生列表(带有属性的Python类/节点和all)。我希望一次渲染一个“学生类”,并使用按钮循环到下一组学生。下面是一个示例,展示了它的外观: app.py @app.route('/', methods=['GET', 'POST']) def get_students(): groups = None # some calculations
@app.route('/', methods=['GET', 'POST'])
def get_students():
groups = None
# some calculations and algorithms
groups = [['foo', 'bar'], ['baz', 'boo']]
return render_template('index.html', groups=groups, index=0)
index.html
{% if groups %}
{% set display_group = groups[index] %}
<ul id="students" class="">
{% for student in display_group %}
<li class="student">{{ student.name }}</li>
{% endfor %}
</ul>
{% endif %}
<button onclick="next_group()">Next Group</button>
<button onclick="prev_group()">Previous Group</button>
{%if组%}
{%set display_group=组[索引]]}
{显示组%中的学生为%0}
- {{student.name}
{%endfor%}
{%endif%}
下一组
前一组
我希望这些按钮重新呈现这个列表,就像索引分别递增/递减一样。我不希望通过URL参数(例如,page_URL/number)完成此操作。如果可能的话,我如何在不刷新页面的情况下实现这种效果?这是javascript的工作,而不是jinja模板系统,当您将模板发送回客户机时,它会根据组成模板的变量进行预格式化。您应该有一个端点可以通过java脚本中的ajax调用调用,而不是返回render_模板,而是返回组的json,并通过JS操作DOM,jinja将无法做到这一点,尽管您可以通过jinja模板系统发送格式化的javascript。这类似于分页。首先,您可以创建一个简单的分页对象,以便更好地帮助正确查找新索引的页面,同时还可以控制下一页和上一页的索引:
import typing
class StudentList(typing.NamedTuple):
name:str
class Pagination:
def __init__(self, _num = 1):
self.num = _num
self.data = [['foo', 'bar'], ['baz', 'boo'], ['first', 'last']]
@property
def has_next(self):
return self.num < len(self.data)
@property
def has_previous(self):
return self.num > 0
@property
def next(self):
return self.num + 1
@property
def previous(self):
return self.num - 1
def __iter__(self):
for i in self.data[self.num-1]:
yield StudentList(i)
第二,显示完整学生分页的页面,以及jquery
和ajax
:
main.html
:
<div class='student_class'>
{%for student in lecture%}
<span class='student'>Name: {{student.name}}</span>
{%endfor%}
{%if lecture.has_previous%}
<button id='previous_{{lecture.previous}}'>Previous</button>
{%endif%}
{%if lecture.has_next%}
<button id='next_{{lecture.next}}'>Next</button>
{%endif%}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('button').click(function(event) {
var result = event.target.id;
$.ajax({
url: "/update_page",
type: "get",
data: {results: result},
success: function(response) {
$("#pagination_results").html(response.html);
},
error: function(xhr) {
$("#pagination_results").html('<p>Opps, something when wrong</p>');
}
});
});
});
</script>
</div>
<html>
<body>
<div id='pagination_results'>
<div class='student_class'>
{%for student in lecture%}
<span class='student'>Name: {{student.name}}</span>
{%endfor%}
{%if lecture.has_previous%}
<button id='previous_{{lecture.previous}}'>Previous</button>
{%endif%}
{%if lecture.has_next%}
<button id='next_{{lecture.next}}'>Next</button>
{%endif%}
</div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('button').click(function(event) {
var result = event.target.id;
$.ajax({
url: "/update_page",
type: "get",
data: {results: result},
success: function(response) {
$("#pagination_results").html(response.html);
},
error: function(xhr) {
$("#pagination_results").html('<p>Opps, something when wrong</p>');
}
});
});
});
</script>
</html>
然后,需要创建从ajax
GET
方法接收数据的路由:
@app.route('/', methods = ['GET'])
def home():
return flask.render_template('main.html', lecture=Pagination())
import re
@app.route('/update_page')
def update_page():
_r = flask.request.args.get('results')
_l = Pagination(int(re.findall('\d+$', _r)[0]))
return flask.jsonify({'html':flask.render_template('students_and_classes.html', lecture=_l)})
注:
分页中的self.data
可以替换为数据库查询等,如果在您的项目中是这样的话
StudentList
用于在所有列表值都是基本数据类型的情况下更清晰地呈现模板。在您的示例中,这是不必要的,正如您提到的,您的列表已经存储了自定义类对象,yield i
可以替换为yield StudentList(i)
谢谢你的回答。我用我的设置得到了这个。我最终序列化了我的对象,这样我就可以通过cookies(而不是数据库查询)检索数据。我遇到的问题有点奇怪。按钮在任一方向只工作一次,然后无法再次操作。脚本事件监听器甚至没有被调用,我也不知道为什么。@adapap我很抱歉,我忘了在
students\u和\u classes.html中包含介于
之间的javascript,而不仅仅是main.html
。当我测试它时,它目前对我有效。请看我最近的编辑。