Flask app search bar

28,354

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'])

to

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

UPDATE

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'])
@login_required
def search():
    form = SearchForm()
    if request.method == 'POST' and form.validate_on_submit():
        return redirect((url_for('search_results', query=form.search.data)))  # or what you want
    return render_template('search.html', form=form)

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

Share:
28,354

Related videos on Youtube

PSNR
Author by

PSNR

https://essen.ai

Updated on October 11, 2020

Comments

  • PSNR
    PSNR over 3 years

    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!

    forms.py

    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'})
    

    views.py

    from flask_login import login_required
    from forms import SearchForm
    from models import User
    
    @app.route('/')
    def index():
      if current_user.is_authenticated:
        return redirect(url_for('profile'))
      return render_template('index.html')
    
    @app.route('/profile', methods=['GET', 'POST'])
    @login_required
    def profile():
      # some code to display user profile page
    
    @app.route('/search', methods=['POST'])
    @login_required
    def search():
      form = SearchForm()
      if not form.validate_on_submit():
        return redirect(url_for('index'))
      return redirect((url_for('search_results', query=form.search.data)))
    
    @app.route('/search_results/<query>')
    @login_required
    def search_results(query):
      results = User.query.whoosh_search(query).all()
      return render_template('search_results.html', query=query, results=results)
    

    models.py

    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)
    

    search.html

    {% extends 'layouts/base.html' %}
    {% set page_title = 'Search' %}
    {% block body %}
        <div>
            {{ render_form(url_for('search'), form) }} # note: render_form is some marco from another .html file
        </div>
    {% endblock %}
    
    • rexbelia
      rexbelia almost 6 years
      can we see what's in the macro .html file?
    • Shravya Mutyapu
      Shravya Mutyapu almost 3 years
      can we used the same with nested dictionaries?
  • PSNR
    PSNR over 7 years
    Thanks, but when I add 'GET', I got 302 error now. It might be helpful that you see the index() in views.py so I just added it
  • dirn
    dirn over 7 years
    A 302 isn't an error. It's the redirect that you send in search.
  • PSNR
    PSNR over 7 years
    yeah but I got ERR_TOO_MANY_REDIRECTS and the search bar won't display on the search page
  • PSNR
    PSNR over 7 years
    Thank you @vishes_shell! It works now. I made some edits to your answer. Thanks for reminding me of PEP-8, it's just I prefer Google 2-space indentation :p