Search code examples
pythonmethodsflaskhttp-status-code-405

"Method Not Allowed The method is not allowed for the requested URL."


I have read through the related posts to this question, but haven't found an answer that fixes or seems to match (apologies if I missed it, I looked through like 10 posts).

Writing a search page that looks for entries in a DB. Initially I wrote this as two separate functions. One to display the search box, and the second to do the actual search and return the results. This works fine, but I'm trying to make this more "user friendly" by keeping the search box at the top of the page and just returning results if there are any.

Seems to be a simple thing to do, but not working.

Python Code in views.app

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

    if request.method == "POST":
        output = []
        searchterm = request.form['lookingfor']
        whichName = request.form['name']
        if searchterm:
            conn = openDB()
            results = findClient(conn, searchterm, whichName)
            for r in results:
                output.append({'id': r[0], 'fname': r[1], 'lname': r[2], 'phonen': r[3], 'email': r[4], 'started': r[5],
                               'opt': r[6], 'signup': r[7], 'enddate': findEndDate(r[7], r[5])})
            closeDB(conn)
            if output:
                message = "Record(s) Found"
            else:
                message = "Nothing found, sorry."
            return render_template('search.html', message=message, output=output)
        else:
            output = []
            message = "Please enter a name in the search box"
            return render_template('search.html', message=message, output=output)
    else:
        return render_template('search.html')

HTML for search.html

{% extends "baseadmin.html" %}
{% block content %}
<div>
    <form action="{{url_for('search')}}" method="post">
        <p>Search for a Client: <input type="text" name="lookingfor"/></p>
        <input type="radio" name="name" value="fname" id="fname"><label for="fname">First Name</label>
        <input type="radio" name="name" value="lname" id="lname"><label for="lname">Last Name</label>
        <input type="submit" value="submit"/>
    </form>
</div>
<h2>{{ message }}</h2>
<div>
    <table>
      <tr>
        <th>Name</th>
        <th>Email Address</th>
        <th>Phone Number</th>
        <th>Trial Method</th>
        <th>Start Date</th>
        <th>EndDate</th>
      </tr>
      {% for client in output %}
        <tr>
          <td>{{ client['fname'] }} {{ client['lname'] }}</td>
          <td>{{ client['email'] }}</td>
          <td>{{ client['phonen'] }}</td>
          <td>{{ client['started'] }}</td>
          <td>{{ client['signup'] }}</td>
          <td>{{ client['enddate'] }}</td>
        </tr>
      {% endfor %}
    </table>
</div>
{% endblock %}

Solution

  • As @dirn already mentioned in his comment, the methods=['POST'] in @app.route('/search', methods=['POST']) means the function SearchForm and the URL '/search' will only accept POST requests. If someone tries to access the page using simply the URL, they would be doing so with a GET request.

    Changing the line to @app.route('/search', methods=['GET', 'POST']) should fix the error.

    (Answered mainly to (1) show the complete solution and to (2) bring visibility to the solution provided by @dirn.)