Query strings in Flask | Learning Flask Ep. 11
Creating, serializing and working with query string data in Flask
In this part of the “Learning Flask” series, we’re going to working with query strings. A query string is part of the URL as a string of parameters and values and are used ubiquitously across the web.
Query strings are essentially a string of key/value pairs sent by the client to the server.
Here’s an example of a query string in the URL from a quick Google search for query string
:
https://www.google.com/search?q=query+string
Let’s break down the URL:
https
is the protocolwww.google.com
is the domain/search
is the path?q=query+string
is the query string
Anatomy of a query string
Focusing on the query string element of the URL, we see the following components:
?
starts the query stringq
is the first parameter=
separates/assigns a value to the parameterquery+string
is the value assigned to theq
parameter
You’ll notice the +
substitution between “query string”. This is because the space charactes is not allowed in a URL so must be replaced with something else.
Spaces in query strings are replaced with +
or %20
Let’s take a look at a slightly more complex query string, again from a Google search for “flask”:
https://www.google.com/search?q=flask&oq=flask&sourceid=chrome&ie=UTF-8
If you take a closer look at the query string, you’ll see multiple parameters and values, separated by the &
symbol.
We use &
to separate parameters and values in the query string. Let’s create a query string below with a few sets of params & values:
http://127.0.0.1:5000/query?foo=foo&bar=bar&baz=baz&title=query+strings+with+flask
Let’s use this query string in our Flask application and learn how to work with it!
Flask query strings
First up, let’s create a new route with the URL /query
:
app/app/views.py
@app.route("/query")
def query():
return "No query string received", 200
If you got to /query
in your browser, you’ll see No query string received
in your window.
Go ahead and paste the query string we just created above into your browser URL bar and see what happens.
You’ll notice we don’t get any errors, however we’re not yet doing anything with our query string. Let’s go ahead and serialize it!
Serializing query strings
To work with any kind of request object or data, we need to import request
from flask:
app/app/views.py
from flask import request
Just like we’ve used request.form
for serializing form data and request.get_json()
to serialize incoming JSON data, we use request.args
to parse and serialize the query string into a Python object.
Let’s store our query string object as a variable called args
and print them:
app/app/views.py
@app.route("/query")
def query():
args = request.args
print(args)
return "No query string received", 200
Save and reload that same URL with the query string, you’ll see the following in your terminal:
ImmutableMultiDict([('foo', 'foo'), ('bar', 'bar'), ('baz', 'baz'), ('title', 'query strings with flask')])
request.args
has parsed our query string and conveniently converted it into an ImmutableMultiDict
which we can treat just like a Python dictionary, for example, change print(args)
for the following:
app/app/views.py
for k, v in args.items():
print(f"{k}: {v}")`
You’ll see our keys and values printed out to the console:
foo: foo
bar: bar
baz: baz
title: query strings with flask`
Just like a dictionary, we can now pluck out values by their key:
@app.route("/query")
def query():
args = request.args
if "foo" in args:
foo = args["foo"]
if "bar" in args:
bar = args.get("bar")
if "baz" in args:
baz = args["baz"]
if "title" in request.args:
title = request.args.get("title")
print(foo, bar, baz, title)
return "No query string received", 200
However at this point we’ll get an error if we don’t send a query string with values for foo
, bar
, baz
and title
.
Let’s refactor our code to mitigate any potantial errors and return a formatted query string to the client:
@app.route("/query")
def query():
if request.args:
# We have our query string nicely serialized as a Python dictionary
args = request.args
# We'll create a string to display the parameters & values
serialized = ", ".join(f"{k}: {v}" for k, v in request.args.items())
# Display the query string to the client in a different format
return f"(Query) {serialized}", 200
else:
return "No query string received", 200
If you re-submit the URL, you’ll see:
(Query) foo: foo, bar: bar, baz: baz, title: query strings with flask
And that pretty much wraps things up for query strings with Flask!
Extras
Although I’ve not found much use for them in the past, the request
object also provides us with a few more features for working with query strings.
request.query_string
will return the query string, for example:
@app.route("/query")
def query():
print(request.query_string)
return "Thanks", 200
Will return:
b'foo=foo&bar=bar&baz=baz&title=query+strings+with+flask'
request.values
will return a CombinedMultiDict
which comines args
with form
, for example:
@app.route("/query")
def query():
print(request.values)
return "Thanks", 200`
Returns:
CombinedMultiDict([ImmutableMultiDict([('foo', 'foo'), ('bar', 'bar'), ('baz', 'baz'),
('title', 'query strings with flask')]), ImmutableMultiDict([])])
Not something I’ve used in the past but can imagine it would be useful to submit a form with query string parameters in the URL.
Wrapping up
Query strings are a convenient way to pass arguments to your application and Flask makes light work of quickly parsing them into something we can work with.
POST requests don’t typically include a query string as they tend to include data that you want to keep within the request body, so you’ll mostly be using them with GET requests.
Last modified · 28 Feb 2019
Written with StackEdit.