Problem description: I have a list of swimmer names stored in Sqlite db at the swimmer table. The list is displayed to the user when clicking on home menu.
When the swimmers option is selected from the menu the list of swimmers is displayed using pagination. You can browse the pages without problem using either the previous page or next page button; also you can even select a specific page and the records show correctly to the user.
On the page that displays the list of swimmers with pagination, at the bottom of the page is a search box and a button to activate the search by name.
For example, when entering the letter "A" in capital letters, the @app.route('/search_swimmers/') searches for all the records that include the letter "A" in the name field and returns this list with pagination. Up to here everything works perfect.
Results of the search for names that include the capital letter "A" in the name field:
When the search results are displayed on the screen. The Name field in the search box no longer includes the capital letter "A" which was the criteria entered for the search. However, all the records found are correct, because they satisfy the search criteria. The example shows a total of nine pages. For purposes of explaining the problem, a maximum number of three records per page has been adjusted. So far everything is correct in what the app is expected to do.
THE PROBLEM: When you want to navigate in the pages, the route @app.route('/search_swimmers/') has lost the value of the name_search variable. As a result, 0 records found are shown.
How could you prevent the value of variable name_search from not being lost?
Attached are the relevant code sections for your review:
app.py:
from flask import Flask
from flask import render_template
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from flask import request, redirect
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Swimmer(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
def __repr__(self):
return '<Swimmer %r>' % self.name
@app.route('/swimmers/<int:page_num>')
def swimmers(page_num):
swimmers_per_page = 3
swimmers = Swimmer.query.paginate(per_page=swimmers_per_page,
page=page_num, error_out=False)
return render_template('swimmers.html',swimmers=swimmers)
@app.route('/search_swimmers/<int:page_num>')
def search_swimmers(page_num):
'''
Search
'''
swimmers_per_page = 3
name_search = str(request.args.get('name'))
swimmers = Swimmer.query.filter(
Swimmer.name.contains(name_search)
).order_by(
Swimmer.name
).paginate(
per_page = swimmers_per_page,
page = page_num,
error_out=False
)
return render_template(
'search_swimmers.html',
swimmers = swimmers,
name_search = name_search
)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
name = request.form['name']
new_stuff = Swimmer(name=name)
try:
db.session.add(new_stuff)
db.session.commit()
return redirect('/')
except IntegrityError as e:
db.session.rollback()
return "There was a problem creating a swimmer."
else:
swimmers = Swimmer.query.order_by(Swimmer.created_at).all()
return render_template('index.html', swimmers=swimmers)
if __name__ == '__main__':
app.run(debug=True)
swimmers.html:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h3>
<span class="d-block p-2 bg-primary text-white">
Swimmers list
</span>
</h3>
<ul class="pagination">
{% if swimmers.has_prev %}
<li class="page-item"> <a class="page-link" href="{{ url_for('swimmers', page_num = swimmers.prev_num ) }}">Previous page</a></li>
{% else %}
<li class="page-item"><a class="page-link btn disabled" href="#">Previous page</a></li>
{% endif %}
{% if swimmers.has_next %}
<li class="page-item"> <a class="page-link" href="{{ url_for('swimmers', page_num = swimmers.next_num) }}">Next page</a></li>
{% else %}
<li class="page-item"><a class="page-link btn disabled" href="#">Next page</a></li>
{% endif %}
</ul>
<p class="text-primary"> Page {{ swimmers.page }} of {{ swimmers.pages }}</p>
{% for page in swimmers.iter_pages(left_edge=3,
right_edge=3,
left_current=3,
right_current=3
)
%}
{% if page %}
<a href="{{ url_for('swimmers',page_num=page) }}">{{page}}</a>
{% else %}
...
{% endif %}
{% endfor %}
{% for swimmer in swimmers.items %}
<div class="alert alert-primary" role="alert">
{{ swimmer.name }}
</div>
{% endfor %}
<p class="text-primary"> Page {{ swimmers.page }} of {{ swimmers.pages }}</p>
{% for page in swimmers.iter_pages(left_edge=3,
right_edge=3,
left_current=3,
right_current=3
)
%}
{% if page %}
<a href="{{ url_for('swimmers',page_num=page) }}">{{page}}</a>
{% else %}
...
{% endif %}
{% endfor %}
<div class="container">
<form action="{{ url_for('search_swimmers',page_num=1) }}" method="get" class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" name="name" placeholder="Name ... " oninvalid="this.setCustomValidity('Please Enter a valid Name')" aria-label="Search" required>
<button class="btn btn-primary my-2 my-sm-0" type="submit"><svg class="bi bi-search" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M10.442 10.442a1 1 0 011.415 0l3.85 3.85a1 1 0 01-1.414 1.415l-3.85-3.85a1 1 0 010-1.415z" clip-rule="evenodd"/>
<path fill-rule="evenodd" d="M6.5 12a5.5 5.5 0 100-11 5.5 5.5 0 000 11zM13 6.5a6.5 6.5 0 11-13 0 6.5 6.5 0 0113 0z" clip-rule="evenodd"/>
</svg></button>
</form>
</div>
</div>
{% endblock content %}
search_swimmers.html:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h3>
<span class="d-block p-2 bg-primary text-white">
Search Swimmers Results
</span>
</h3>
<p class="text-primary">Total pages: {{ swimmers.pages }}</p>
{% for page in swimmers.iter_pages(left_edge=3,
right_edge=3,
left_current=3,
right_current=3
)
%}
{% if page %}
<a href="{{ url_for('search_swimmers',page_num=page) }}">{{page}}</a>
{% else %}
...
{% endif %}
{% endfor %}
{% for swimmer in swimmers.items %}
<div class="alert alert-primary" role="alert">
{{ swimmer.name }}
</div>
{% endfor %}
<p class="text-primary">Total pages: {{ swimmers.pages }}</p>
{% for page in swimmers.iter_pages(left_edge=3,
right_edge=3,
left_current=3,
right_current=3
)
%}
{% if page %}
<a href="{{ url_for('search_swimmers',page_num=page) }}">{{page}}</a>
{% else %}
...
{% endif %}
{% endfor %}
<div class="container">
<form action="{{ url_for('search_swimmers',page_num=1) }}" method="get" class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" name="name" placeholder="Name ... " aria-label="Search">
<button class="btn btn-primary my-2 my-sm-0" type="submit"><svg class="bi bi-search" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M10.442 10.442a1 1 0 011.415 0l3.85 3.85a1 1 0 01-1.414 1.415l-3.85-3.85a1 1 0 010-1.415z" clip-rule="evenodd"/>
<path fill-rule="evenodd" d="M6.5 12a5.5 5.5 0 100-11 5.5 5.5 0 000 11zM13 6.5a6.5 6.5 0 11-13 0 6.5 6.5 0 0113 0z" clip-rule="evenodd"/>
</svg></button>
</form>
</div>
</div>
{% endblock content %}
Any guide is highly appreciated. Thank you!





