Search - csemanish12/flask_blog GitHub Wiki
Since there will be several posts in our application, lets add a functionality for users so that they can search for posts based on the title.
We will add search field in our navigation bar. lets add these codes in our layout.html inside div with class "navbar-nav" just above our "{% if current_user.is_authenticated %}" control statement.
<form class="form-inline" action="{{ url_for('search') }}" method="POST">
<i class="fas fa-search" aria-hidden="true"></i>
<input class="form-control form-control-sm ml-3 w-75" type="text" placeholder="search" name="search" aria-label="Search">
</form>lets create new route for search
.
from flask import session
.
@app.route("/search", methods=["GET", "POST"])
def search():
page = request.args.get('page', 1, type=int)
if request.method == 'POST':
search_word = request.form['search']
session['search'] = search_word
if 'search' in session:
posts = Post.query.filter(Post.title.ilike(F'%{session["search"]}%')).paginate(per_page=3, page=page)
else:
posts = Post.query.order_by(Post.date_posted.desc()).paginate(per_page=3, page=page)
return render_template('search_page.html', posts=posts, title_name="Search", search_word=session.get('search'))since there will be lots of results while searching for a post, we will add pagination in our search results as well. To know the previous search word that user entered while clicking on next page, we will use session to store the search word. Every time user enters new word, we will replace the search word in our session.
lets create a page for displaying search results and name it search_page.html. We will copy the codes from home.html for starting points. Our search_page.html should look like this:
{% extends 'layout.html' %}
{% block content %}
<h2>Search results for "{{ search_word }}" found {{posts.total}} posts</h2>
{% for post in posts.items %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ url_for('static', filename='profile_pictures/' + post.author.image_file) }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ post.author.username }}</a>
<small class="text-muted">{{ post.date_posted.strftime('%Y-%m-%d') }}</small>
</div>
<h2><a class="article-title" href="{{ url_for('post', post_id=post.id) }}">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content }}</p>
</div>
</article>
{% endfor %}
{% if posts.has_next and posts.has_prev %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('search', page=posts.page - 1) }}">Previous</a>
<a class="btn btn-info mb-4" href="{{ url_for('search', page=posts.page ) }}">{{ posts.page }}</a>
<a class="btn btn-outline-info mb-4" href="{{ url_for('search', page=posts.page + 1) }}">Next</a>
{% elif posts.has_next %}
<a class="btn btn-info mb-4 ml-4" href="{{ url_for('search', page=posts.page ) }}">{{ posts.page }}</a>
<a class="btn btn-outline-info mb-4" href="{{ url_for('search', page=posts.page + 1) }}">Next</a>
{% elif posts.has_prev %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('search', page=posts.page -1 ) }}">Previous</a>
<a class="btn btn-info mb-4" href="{{ url_for('search', page=posts.page ) }}">{{ posts.page}}</a>
{% endif %}
{% endblock content %}lets update our search field to display the search text when user navigates to next or previous page. We will update our input element in our search form in layout.html as follows:
.
<input class="form-control form-control-sm ml-3 w-75" type="text" placeholder="search" name="search" aria-label="Search" value="{% if search_word %}{{search_word}} {% else %} search {% endif %}">
.Implementation can be found over this commit