在Flask中,我试图在多个页面中显示项目的动态列表。列表的大小可能超过1000。
在app.py
我有一条路线,例如:
@app.route('/displayitems')
def displayitems():
item_list = ['item1', 'item2', 'item3'] # Up to 1000 items
return render_template('displayitems.html', item_list=item_list)
然后在displayitems.html
我有:
{% for item in itemList%}
<li class="list-group-item">
<div class="item_number">{{ loop.index }}</div>
<div class="item_name">{{ item }}</div>
</li>
{% endfor %}
其中列出了同一页面上的所有项目。但是,我想以某种方式在一个页面上拥有前20个项目,然后能够点击&#34; next&#34;按钮可以查看另一个页面上的下20个项目,依此类推查看列表中的所有项目。有谁知道这样做的最好方法?
答案 0 :(得分:1)
首先,您需要创建一个pagenation对象以传递给包裹的路径方法render_template
:
class PageResult:
def __init__(self, data, page = 1, number = 20):
self.__dict__ = dict(zip(['data', 'page', 'number'], [data, page, number]))
self.full_listing = [self.data[i:i+number] for i in range(0, len(self.data), number)]
def __iter__(self):
for i in self.full_listing[self.page-1]:
yield i
def __repr__(self): #used for page linking
return "/displayitems/{}".format(self.page+1) #view the next page
@app.route('/displayitems/<pagenum>')
def displayitems(pagenum):
item_list = ['item1', 'item2', 'item3']
return render_template('displayitems.html', listing = PageResult(item_list, pagenum))
然后,在您的模板中,使用bootstrap和当前列表创建分页:
<ul>
{%for item in listing%}
<li>{{item}}</li>
{%endfor%}
</ul>
<ul class="pagination">
{%if listing.page == 1%}
<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
{%else%}
<li class="page-item"><a class="page-link" href="/displayitems/{{listing.page-1}}">Previous</a></li>
{%endif%}
<li class="page-item"><a class="page-link" href="{{listing}}">Next</a></li>
</ul>
答案 1 :(得分:0)
您正在寻找分页功能,该功能不直接包含在Flask框架中。你应该考虑使用像Flask-paginate
这样的东西答案 2 :(得分:0)
您可以这样做:
@app.route('/displayitems/<page>/')
def displayitems(page=1):
items_per_page = 20
item_list = ['item1', 'item2', 'item3', etc..]
start_pos = 0 if page == 1 else items_per_page * (page - 1)
return render_template('displayitems.html', item_list=item_list[start_pos: start_pos + items_per_page])
当您的网页加载时,请致电http://your_domain/displayitems/1/
,然后在每次&#34; next&#34;之后调用它来增加页码。单击按钮。
注意:
确保start_pos
和start_pos + items_per_page
&lt; len(item_list)
或者您将获得例外。
答案 3 :(得分:0)
我需要做类似的事情。在观看Corey Schafer的Flask教程中有关分页的知识之后,我找到了一种简单的方法。由于我不使用数据库(具有用于分页的内置功能),因此需要对其进行一些更改。我的编码方式如下:
@app.route('/home')
def home(): #this doesn't make a request
#pagination
current_page = request.args.get('page', 1, type=int)
#the variable page will store the (integer) part after '?page=' from the url
#http://localhost:5000/?page=1
#http://localhost:5000/?page=2
#pages, per page
items_per_page= 20
pages = round(len(item_list)/items_per_page+ .499) #the .499 is for rounding to the upside
from_page = int(page) * items_per_page - items_per_page #36 per page
upto_page = int(page) * items_per_page
list_part = item_list[from_page:upto_page]
return render_template('displayitems.html', list_part=list_part, pages=pages, current_page=current_page)
因此,您无需提供完整列表item_list=item_list
,而是提供该列表list_part=list_part
的一部分。要在模板中呈现分页:
{% for page_num in range(1, pages) %}
{% if page_num in [1, 2, 3, current_page, current_page-1, current_page+1, pages-3, pages-2, pages-1] %}
{% if current_page == page_num %}
<a class="btn btn-info mb-4" href="{{ url_for('home', page=page_num) }}">{{ page_num }}</a>
{% else %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('home', page=page_num) }}">{{ page_num }}</a>
{% endif %}
{% elif current_page > 4 and page_num == 4 %}
....
{% elif current_page < pages-4 and page_num == pages-4 %}
....
{% endif %}
{% endfor %}
我没有使用下一个/上一个按钮(我将在有解决办法和时间的时候添加此按钮)。但是,即使是一长串的列表,其样式也很好,用省略号表示有更多页面,但没有显示所有页面。活动页面的按钮具有不同的类别,以显示您所在的页面。
您可以通过更改网址http://localhost:5000/?page=1
中?page =之后的整数来快速转到页面。编辑: 要添加下一个/上一个按钮,请在for循环外放置以下Flask if块。
{% if current_page != 1 %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('home', page=current_page-1) }}"><<</a>
{% endif %}
{% for page_num in range(1, pages) %}
...........[SAME PART AS ABOVE]..........
{% endfor %}
{% if current_page != pages %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('home', page=current_page+1) }}">>></a>
{% endif %}