Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To add a basic read-only search in Flask, create a GET route, give the form input a name such as q, read it with request.args.get("q", ""), run your application’s matching logic, and pass the query and results to a template. Flask receives the search term; it does not search your data automatically.

How a Flask search form works

The browser submits the form to a URL such as /search?q=flask. Flask routes that request to a view function, where request.args provides the query-string values. The view then asks your application’s data source to find matches and renders a page with the query and results.

For a read-only search, GET is a straightforward choice: the URL shows the submitted term, making the search easy to bookmark or share. Do not use GET for secrets or sensitive terms; URLs can appear in browser history, logs, and shared links. Flask’s official Quickstart documents routing, request data, templates, and HTML escaping.

Build the route, form, and template

1. Add a GET route

Flask routes accept GET by default. The following pattern reads an optional query parameter and passes the data to a template:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from flask import Flask, render_template, request

app = Flask(__name__)

@app.get("/search")
def search():
    query = request.args.get("q", "")
    results = find_matches(query)  # Define this for your data source.
    return render_template("search.html", query=query, results=results)

find_matches() is deliberately application-specific: replace it with the code that searches your records, files, API, or other data source. Flask parses the request but does not supply this matching function.

Using .get("q", "") gives the view an empty string when the parameter is absent. Flask recommends using get or handling a missing-key error because users can edit URL parameters; directly indexing a missing key can raise an error.

2. Add a form with a matching input name

Create templates/search.html and include a GET form. The input’s name must match the key the view reads:

<form action="/search" method="get">
  <label for="q">Search</label>
  <input id="q" name="q" type="search" value="{{ query }}">
  <button type="submit">Search</button>
</form>

{% if query %}
  <h1>Results for {{ query }}</h1>
{% endif %}

{% if results %}
  <ul>
  {% for result in results %}
    <li>{{ result.title }}</li>
  {% endfor %}
  </ul>
{% elif query %}
  <p>No matches found.</p>
{% endif %}

Flask’s render_template() looks for templates in a templates directory associated with the application module or package. Normal Jinja template rendering escapes values such as {{ query }} in HTML, which helps prevent injection. Do not construct HTML by concatenating untrusted query text, or mark untrusted values as safe. Apply the same care to result content.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Check the three pieces agree

  • The form submits to /search, the route’s URL.
  • The form uses method="get", so the value is in the URL query string.
  • The input uses name="q", matching request.args.get("q", "").

Choose GET or POST for the operation

Method Where Flask reads the submitted value Typical fit URL behavior
GET request.args Read-only searches The query appears in the URL and can be bookmarked or shared.
POST request.form Form submissions that change state, or cases where body submission fits the application The form data is sent in the request body rather than as URL query parameters.

request.form is for form data sent with POST or PUT; it is not where a GET search form’s query appears. Flask documents these request properties but does not mandate a design for every search feature.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle empty searches and no matches

Decide what an empty query should do in your application. The example leaves the results section out until a term is entered; another reasonable choice is to show all records or ask the user to enter a term. Avoid running an expensive or overly broad search accidentally when the query is blank.

When a non-empty query has no matches, display a clear no-results message rather than an empty list that looks broken. The exact behavior depends on your data and product requirements, not on Flask.

Common mistakes to avoid

  • Reading request.form for a GET submission: use request.args for query-string values.
  • Mismatched names: an input named search will not populate a lookup for q.
  • Assuming a parameter always exists: use request.args.get() with an appropriate default or handle the missing key.
  • Expecting Flask to search your database: implement matching for the application’s own data source.
  • Rendering user input as raw HTML: use normal Jinja templates and keep untrusted values escaped.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.