Shuai Shuai - 1 year ago 267
Python Question

Flask app search bar

I am trying to implement a search bar using Flask, but when I enter the url/search, I got a 405 error, Method Not Allowed.

Here is a snippet of my code. Any help would be appreciated!

from wtforms import StringField
from wtforms.validators import DataRequired

class SearchForm(Form):
search = StringField('search', [DataRequired()])
submit = SubmitField('Search',
render_kw={'class': 'btn btn-success btn-block'})

from flask_login import login_required
from forms import SearchForm
from models import User

def index():
if current_user.is_authenticated:
return redirect(url_for('profile'))
return render_template('index.html')

@app.route('/profile', methods=['GET', 'POST'])
def profile():
# some code to display user profile page

@app.route('/search', methods=['POST'])
def search():
form = SearchForm()
if not form.validate_on_submit():
return redirect(url_for('index'))
return redirect((url_for('search_results',

def search_results(query):
results = User.query.whoosh_search(query).all()
return render_template('search_results.html', query=query, results=results)

from flask_sqlalchemy import SQLAlchemy
from flask_whooshalchemy import whoosh_index
from app import app

db = SQLAlchemy()

class User(db.model):
__searchable__ = ['name']
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))

whoosh_index(app, User)


{% extends 'layouts/base.html' %}
{% set page_title = 'Search' %}
{% block body %}
{{ render_form(url_for('search'), form) }} # note: render_form is some marco from another .html file
{% endblock %}

Answer Source

Because when you load page manually you using GET method, but only POST is allowed for search controller. You need to change

@app.route('/search', methods=['POST'])


@app.route('/search', methods=['GET', 'POST'])


So basically it's better to change your search controller. Because it's not using search.html and works wrong.

@app.route('/search', methods=['GET', 'POST'])
def search():
    form = SearchForm()
    if request.method == 'POST' and form.validate_on_submit():
        return redirect((url_for('search_results',  # or what you want
    return render_template('search.html', form=form)

Also make indentation 4 spaces, as it said in PEP-8

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download