You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Flask健康主题搜索引擎实现结果分页功能?

Flask健康维基搜索引擎分页实现方案

我用Flask开发了一个检索健康主题维基百科语料的搜索引擎,部分查询会返回数百条结果,需要添加分页功能(每页展示10-20条)。当前页面底部已有分页按钮但无实际功能,我尝试引入flask_paginate配置后端分页逻辑,但不清楚如何修改index.html实现前端分页展示。以下是我的相关代码:

原index.html代码

{% extends "base.html" %}
{% block title %}Search Page{% endblock %}
{% block contents %}

  <div class="container">
    <div class="row">
      <div class="col-lg-12">
        <div class="search-result-box card-box">
          <div class="row">
            <div class="col-md-8 offset-md-2">
              <div class="pt-3 pb-4">
                <div class="search-form">
                  <form action="#" method="POST">
                      <div class="input-group">
                        <input type="text" name="msg" class="form-control input-lg">                    
                        <div class="input-group-btn">
                          <button class="btn  btn-primary" type="submit">Search</button>
                        </div>
                      </div>
                  </form>
                </div>

                <div class="mt-4 text-center"><h4>Search Results For {{user_query}}</h4></div>
              </div>
            </div>
          </div>
          <!-- end row -->
          <ul class="nav nav-tabs tabs-bordered">
              <li class="nav-item"><a href="#home" data-toggle="tab" aria-expanded="true" class="nav-link active">All results <span class="badge badge-success ml-1">{{search_results_list|length}}</span></a></li>
          </ul>
             <div class="tab-content">
                <div class="tab-pane active" id="home">
                    <div class="row">
                        <div class="col-md-12">
                            <div class="search-item">
                                {% if search_results_list|length > 0 %}

                                {% for r in search_results_list %}

                                <div class="font-13 text-success mb-3"><a href='{{r[0]}}' target="_blank">{{r[0]}}</a></div>
                                <div class="font-13 text-success mb-3"><p target="_blank">{{r[1]}}</p></div>

                                {% endfor %}
                                {% else %}
                                <p class="mt-4 text-center">No search result</P>
                                {% endif %}
                              </div>
                                <ul class="pagination justify-content-end pagination-split mt-0">
                                  <li class="page-item"><a class="page-link" href="#" aria-label="Previous"><span aria-hidden="true">«</span> <span class="sr-only">Previous</span></a></li>
                                  <li class="page-item active"><a class="page-link" href="#">1</a></li>
                                  <li class="page-item"><a class="page-link" href="#" aria-label="Next"><span aria-hidden="true">»</span> <span class="sr-only">Next</span></a></li>
                              </ul>
                              <div class="clearfix"></div>
                           </div>
                     </div>
                </div>
                <!-- end All results tab -->

              </div>
            </div>
         </div>
        </div>
        <!-- end row -->
  </div>
  <!-- Footer -->
  <footer id="main-footer" class="pt-2 py-4 bg-dark text-white text-center">
    Copyright &copy;
    <span class="year"></span> Team Dream
  </footer>
  <!-- container -->


{% endblock %}

原Flask后端代码

from flask import Flask, render_template, request
from search_engine import query_prep, OkapiBM25
import pickle

app = Flask(__name__)

@app.route('/')
def results():
    return render_template('index.html')

@app.route('/', methods=['POST'])
def process_res():
    with open("inv_index.pickle", "rb") as file:
        inv_ind = pickle.load(file)
    user_search_query = request.form['msg']
    queries = {'q': query_prep(user_search_query)}
    ranking = OkapiBM25(inv_ind, queries)['q']
    seen = set()

    newRes= []
    myDict = pickle.load(open('text_summaries.pickle','rb'))
    
    for r in ranking:
        newRes.append((r[1], myDict[r[1]]))

    return render_template('index.html', search_results_list = newRes,
                                          user_query=user_search_query)

if __name__ == "__main__":
    app.run(debug=True)

修改后的分页相关后端代码

from flask_paginate import Pagination, get_page_parameter

def process_res():
    with open("inv_index.pickle", "rb") as file:
        inv_ind = pickle.load(file)
    user_search_query = request.form['msg']
    queries = {'q': query_prep(user_search_query)}
    ranking = OkapiBM25(inv_ind, queries)['q']
    seen = set()

    newRes= []
    myDict = pickle.load(open('text_summaries.pickle','rb'))
    
    for r in ranking:
        newRes.append((r[1], myDict[r[1]]))

    page = request.args.get(get_page_parameter(), type=int, default=1)
    pagination = Pagination(page=page, total=len(newRes), search=user_search_query, record_name='Search Results')
    return render_template('index.html', search_results_list = newRes,
                                          user_query=user_search_query,
                                          Pagination = pagination)

解决方案

1. 修正后端分页逻辑

当前后端仅初始化了Pagination对象,但未对结果列表做分页截取,也未指定每页展示数量。修改后的完整后端代码如下:

from flask import Flask, render_template, request, session
from search_engine import query_prep, OkapiBM25
import pickle
from flask_paginate import Pagination, get_page_parameter

app = Flask(__name__)
app.secret_key = 'your_custom_secret_key_here'  # 必须设置session密钥

@app.route('/')
def results():
    return render_template('index.html')

@app.route('/', methods=['POST', 'GET'])
def process_res():
    # 处理搜索请求
    if request.method == 'POST':
        user_search_query = request.form['msg']
        # 保存搜索关键词和结果到session,分页时复用
        session['search_query'] = user_search_query
        
        with open("inv_index.pickle", "rb") as file:
            inv_ind = pickle.load(file)
        queries = {'q': query_prep(user_search_query)}
        ranking = OkapiBM25(inv_ind, queries)['q']
        
        newRes= []
        myDict = pickle.load(open('text_summaries.pickle','rb'))
        for r in ranking:
            newRes.append((r[1], myDict[r[1]]))
        
        session['all_results'] = newRes
    else:
        # 分页请求时从session获取历史数据
        user_search_query = session.get('search_query', '')
        newRes = session.get('all_results', [])
    
    # 分页核心配置
    page = request.args.get(get_page_parameter(), type=int, default=1)
    per_page = 10  # 每页展示10条,可调整为20
    start = (page - 1) * per_page
    end = start + per_page
    paginated_results = newRes[start:end]
    
    pagination = Pagination(
        page=page,
        total=len(newRes),
        per_page=per_page,
        record_name='搜索结果',
        css_framework='bootstrap4'  # 匹配你的Bootstrap版本
    )
    
    return render_template(
        'index.html',
        search_results_list=paginated_results,
        user_query=user_search_query,
        pagination=pagination
    )

if __name__ == "__main__":
    app.run(debug=True)

关键修改说明:

  • 路由新增GET方法支持,分页请求为GET类型
  • 使用session存储搜索关键词和全部结果,避免分页时重复执行搜索逻辑
  • 添加per_page参数控制每页条数,对结果列表做切片得到当前页数据
  • 指定css_framework适配前端Bootstrap样式,自动生成符合UI的分页组件

2. 修改前端index.html模板

替换静态分页按钮为flask_paginate生成的动态组件,同时优化结果展示逻辑:

{% extends "base.html" %}
{% block title %}Search Page{% endblock %}
{% block contents %}

  <div class="container">
    <div class="row">
      <div class="col-lg-12">
        <div class="search-result-box card-box">
          <div class="row">
            <div class="col-md-8 offset-md-2">
              <div class="pt-3 pb-4">
                <div class="search-form">
                  <form action="#" method="POST">
                      <div class="input-group">
                        <input type="text" name="msg" class="form-control input-lg" value="{{ user_query or '' }}">                    
                        <div class="input-group-btn">
                          <button class="btn  btn-primary" type="submit">Search</button>
                        </div>
                      </div>
                  </form>
                </div>

                {% if user_query %}
                <div class="mt-4 text-center"><h4>Search Results For {{user_query}}</h4></div>
                {% endif %}
              </div>
            </div>
          </div>
          <!-- end row -->
          {% if search_results_list %}
          <ul class="nav nav-tabs tabs-bordered">
              <li class="nav-item"><a href="#home" data-toggle="tab" aria-expanded="true" class="nav-link active">All results <span class="badge badge-success ml-1">{{ search_results_list|length }}</span></a></li>
          </ul>
             <div class="tab-content">
                <div class="tab-pane active" id="home">
                    <div class="row">
                        <div class="col-md-12">
                            <div class="search-item">
                                {% for r in search_results_list %}
                                <div class="font-13 text-success mb-3"><a href='{{r[0]}}' target="_blank">{{r[0]}}</a></div>
                                <div class="font-13 text-muted mb-3"><p>{{r[1]}}</p></div>
                                {% endfor %}
                              </div>
                              <!-- 替换静态分页为动态组件 -->
                              <div class="d-flex justify-content-end mt-4">
                                  {{ pagination.links }}
                              </div>
                              <div class="clearfix"></div>
                           </div>
                     </div>
                </div>
                <!-- end All results tab -->
              </div>
              {% else %}
              {% if user_query %}
              <p class="mt-4 text-center">No search result</p>
              {% endif %}
              {% endif %}
            </div>
         </div>
        </div>
        <!-- end row -->
  </div>
  <!-- Footer -->
  <footer id="main-footer" class="pt-2 py-4 bg-dark text-white text-center">
    Copyright &copy;
    <span class="year"></span> Team Dream
  </footer>
  <!-- container -->

{% endblock %}

关键修改说明:

  • 搜索框默认填充历史查询关键词,提升用户体验
  • 移除静态分页按钮,使用{{ pagination.links }}自动生成带跳转功能的分页组件
  • 优化空结果判断逻辑,避免初始页面显示"No search result"
  • 微调摘要文本样式,避免和链接颜色重复

内容的提问来源于stack exchange,提问作者hulio_entredas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:20:25