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:
#1 Best Overall
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.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Rank #3
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", matchingrequest.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.
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.
Quick Recap
Best Value
Common mistakes to avoid
- Reading
request.formfor a GET submission: userequest.argsfor query-string values. - Mismatched names: an input named
searchwill not populate a lookup forq. - 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.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →

