使用 flask-paginate 0.4.5 在一页上进行 Flask 许多分页
Flask Many Pagination on One Single Page using flask-paginate 0.4.5
我想使用 flask-paginate 在一个页面上呈现三个分页。
问题是三个分页是 "synchronized" 在某种意义上单击一个分页的 'Next Page' 也会影响另一个分页。
我曾尝试使用不同的页面名称来进行不同的分页,但仍然缺少一些东西。
我还没有发现关于多重分页的任何信息,请帮助我解决这个问题。
请查看所附图片以更好地理解。
请注意,我在创建此应用程序时遵循了 Miguel Gringberg 的书,但他只考虑单页而不是多页。 https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
我有一个包含 3 个分页元素列表的页面“'discover.html'”:
<div class="discover-content">
<div class="contests-list">
{% with projects=contests, pagination=contests_pagination, page='main.discover', fragment='#contests' %}
<h2>Most Recent Contests</h2>
{% include '_contests.html' %}
{% endwith %}
</div>
<div class="skills-list">
{% with skills=skills, pagination=skills_pagination, page='main.discover', fragment='#skills' %}
<h2>Skills</h2>
{% include '_skills.html' %}
{% endwith %}
</div>
<div class="ideas-list">
{% with projects=ideas, pagination=ideas_pagination, page='main.discover', fragment='#ideas' %}
<h2>Most Recent Ideas</h2>
{% include '_ideas.html' %}
{% endwith %}
</div>
</div>
每个列表如下所示''_skills.html'':
{% import "_macros.html" as macros %}
<ul class="skills">
{% for skill in skills %}
{% if skill.name %}
<li class="skill">{{ skill.name }}</li>
{% endif %}
{% endfor %}
</ul>
{% if pagination %}
<div class="pagination">
{{ macros.pagination_widget(pagination, page, fragment=fragment) }}
</div>
{% endif %}
文件“_macros.html”的工作方式如下:
{% macro pagination_widget(pagination, endpoint, fragment='') %}
<ul class="pagination">
<li{% if not pagination.has_prev %} class="disabled"{% endif %}>
<a href="{% if pagination.has_prev %}{{ url_for(endpoint, page=pagination.prev_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}">
«
</a>
</li>
{% for p in pagination.iter_pages() %}
{% if p %}
{% if p == pagination.page %}
<li class="active">
<a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a>
</li>
{% else %}
<li>
<a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a>
</li>
{% endif %}
{% else %}
<li class="disabled"><a href="#">…</a></li>
{% endif %}
{% endfor %}
<li{% if not pagination.has_next %} class="disabled"{% endif %}>
<a href="{% if pagination.has_next %}{{ url_for(endpoint, page=pagination.next_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}">
»
</a>
</li>
</ul>
{% endmacro %}
与页面“'discover.html'”关联的视图如下:
@main.route('/discover', defaults={'page_c': 1, 'page_i': 1, 'page_s': 1}, methods=['GET', 'POST'])
@main.route('/discover/page_c/<int:page_c>/page_i/<int:page_i>/page_s/<int:page_s>', methods=['GET', 'POST'])
def discover(page_c, page_i, page_s):
contests_page = request.args.get(page_c, 1, type=int)
contests_pagination = Project.query.filter_by(project_type='contest').order_by(Project.timestamp.desc()).paginate(
contests_page, per_page=current_app.config['CONTESTS_PER_PAGE'], error_out=False)
contests = contests_pagination.items
ideas_page = request.args.get(page_i, 1, type=int)
ideas_pagination = Project.query.filter_by(project_type='idea').order_by(Project.timestamp.desc()).paginate(
ideas_page, per_page=current_app.config['IDEAS_PER_PAGE'], error_out=False)
ideas = ideas_pagination.items
skills_page = request.args.get(page_s, 1, type=int)
skills_pagination = Skill.query.order_by(Skill.name.desc()).paginate(
skills_page, per_page=current_app.config['SKILLS_PER_PAGE'], error_out=False)
skills = skills_pagination.items
return render_template('discover.html', contests=contests, ideas=ideas, skills=skills,
contests_pagination=contests_pagination, ideas_pagination=ideas_pagination,
skills_pagination=skills_pagination)
最明确的处理方式是使用异步请求 (Ajax)。对于三个项目列表,您将拥有三个独立的端点,每个端点都单独分页。 HTML 主页面将向这三个端点发出 Ajax 请求,并且在一个列表中的页面之间移动根本不会影响其他两个列表。
如果您想继续将其作为包含三个列表的单个页面进行操作,则必须确保所有列表中的分页 link 包含所有三个列表的正确页码.例如,如果您分别在这三个列表中查看第 1、2 和 3 页,然后在第二个列表中点击下一页,则下一页 link 应该转到 /discover/page_c/1/page_i/3/page_s/3
,这样第一个和第三个列表保留在它们的第 1 页和第 3 页上,第二个列表从第 2 页移动到第 3 页。您的宏将需要更多的复杂性,它需要知道三个列表的页码,以及哪一个列表正在更改。
我有一个包含 3 个分页元素列表的页面“'discover.html'”:
<div class="discover-content">
<div class="contests-list">
{% with projects=contests, pagination=contests_pagination, page='main.discover', fragment='#contests' %}
<h2>Most Recent Contests</h2>
{% include '_contests.html' %}
{% endwith %}
</div>
<div class="skills-list">
{% with skills=skills, pagination=skills_pagination, page='main.discover', fragment='#skills' %}
<h2>Skills</h2>
{% include '_skills.html' %}
{% endwith %}
</div>
<div class="ideas-list">
{% with projects=ideas, pagination=ideas_pagination, page='main.discover', fragment='#ideas' %}
<h2>Most Recent Ideas</h2>
{% include '_ideas.html' %}
{% endwith %}
</div>
</div>
每个列表如下所示''_skills.html'':
{% import "_macros.html" as macros %}
<ul class="skills">
{% for skill in skills %}
{% if skill.name %}
<li class="skill">{{ skill.name }}</li>
{% endif %}
{% endfor %}
</ul>
{% if pagination %}
<div class="pagination">
{{ macros.pagination_widget(pagination, page, fragment=fragment) }}
</div>
{% endif %}
文件“_macros.html”的工作方式如下:
{% macro pagination_widget(pagination, endpoint, fragment='') %}
<ul class="pagination">
<li{% if not pagination.has_prev %} class="disabled"{% endif %}>
<a href="{% if pagination.has_prev %}{{ url_for(endpoint, page=pagination.prev_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}">
«
</a>
</li>
{% for p in pagination.iter_pages() %}
{% if p %}
{% if p == pagination.page %}
<li class="active">
<a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a>
</li>
{% else %}
<li>
<a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a>
</li>
{% endif %}
{% else %}
<li class="disabled"><a href="#">…</a></li>
{% endif %}
{% endfor %}
<li{% if not pagination.has_next %} class="disabled"{% endif %}>
<a href="{% if pagination.has_next %}{{ url_for(endpoint, page=pagination.next_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}">
»
</a>
</li>
</ul>
{% endmacro %}
与页面“'discover.html'”关联的视图如下:
@main.route('/discover', defaults={'page_c': 1, 'page_i': 1, 'page_s': 1}, methods=['GET', 'POST'])
@main.route('/discover/page_c/<int:page_c>/page_i/<int:page_i>/page_s/<int:page_s>', methods=['GET', 'POST'])
def discover(page_c, page_i, page_s):
contests_page = request.args.get(page_c, 1, type=int)
contests_pagination = Project.query.filter_by(project_type='contest').order_by(Project.timestamp.desc()).paginate(
contests_page, per_page=current_app.config['CONTESTS_PER_PAGE'], error_out=False)
contests = contests_pagination.items
ideas_page = request.args.get(page_i, 1, type=int)
ideas_pagination = Project.query.filter_by(project_type='idea').order_by(Project.timestamp.desc()).paginate(
ideas_page, per_page=current_app.config['IDEAS_PER_PAGE'], error_out=False)
ideas = ideas_pagination.items
skills_page = request.args.get(page_s, 1, type=int)
skills_pagination = Skill.query.order_by(Skill.name.desc()).paginate(
skills_page, per_page=current_app.config['SKILLS_PER_PAGE'], error_out=False)
skills = skills_pagination.items
return render_template('discover.html', contests=contests, ideas=ideas, skills=skills,
contests_pagination=contests_pagination, ideas_pagination=ideas_pagination,
skills_pagination=skills_pagination)
最明确的处理方式是使用异步请求 (Ajax)。对于三个项目列表,您将拥有三个独立的端点,每个端点都单独分页。 HTML 主页面将向这三个端点发出 Ajax 请求,并且在一个列表中的页面之间移动根本不会影响其他两个列表。
如果您想继续将其作为包含三个列表的单个页面进行操作,则必须确保所有列表中的分页 link 包含所有三个列表的正确页码.例如,如果您分别在这三个列表中查看第 1、2 和 3 页,然后在第二个列表中点击下一页,则下一页 link 应该转到 /discover/page_c/1/page_i/3/page_s/3
,这样第一个和第三个列表保留在它们的第 1 页和第 3 页上,第二个列表从第 2 页移动到第 3 页。您的宏将需要更多的复杂性,它需要知道三个列表的页码,以及哪一个列表正在更改。