search

Home  >  Q&A  >  body text

How to split Flask search engine results into different pages?

I used Flask to create a search engine that returns search results from the Wikipedia corpus generated from articles related to health topics. Some queries return hundreds of results, so I want to add a feature to split the results into multiple pages. The following is the index.html code that generates the web page:

{% 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 %}

I don't have much experience creating web pages with HTML, so I'm not entirely sure how to add this functionality. Here's also the Python code to generate the application:

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)

This code opens a pickle file using the inverted index of the corpus, then runs a query against that index, ranks the results and returns them. A text summary of each Wikipedia article is also shown below each search result. If you want to try it out and see what I'm trying to do, here is the deployed version of the page: https://searchenginecapstone.herokuapp.com/

If you search for "health" you'll see 442 results on one page. I'd like to adjust the code (I think this will be done in the HTML part only - but not entirely sure) to split the results into 10-20 chunks. There is already a button for the page in the lower right corner of the page, but it currently does nothing. I appreciate any help or ideas you can provide. If there's anything else you need to see from a coding perspective to answer this question, please let me know.

I discovered that Flask has native support for pagination with the paginate() method, so if I modify what is returned in render_template() using:

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)

The page seems to work (no pagination occurs), so I guess I have to update the index file to reflect the pagination changes, but I don't know how.

P粉614840363P粉614840363335 days ago445

reply all(1)I'll reply

  • P粉883223328

    P粉8832233282024-02-04 11:45:31

    If you use the Flask-SQLAlchemy extension, you can use the paginate() method to split the search engine results into different pages.

    reply
    0
  • Cancelreply