Blog Post 3
In this post, we’re going to create a simple web app that allows users to input a message, as well as their name or handle, and allow users to view five random messages they’ve submitted. We’ll be using the flask library. To store the messages, we use a database file and use SQL queries to view the stored messages. Here’s a link to my project repository.
The get_message_db() Function
To initialize the table of messages in our database, we use the sqllite3 library and SQL. We check if the message_db
database is in our app first, and once it’s connected, we create a messages
table inside it to store our messages.
def get_message_db():
# if message_db isn't in the g attribute of the app, connect it to the messages_db.sqlite database
if "message_db" not in g:
g.message_db = sqlite3.connect("messages_db.sqlite")
cursor = g.message_db.cursor()
# create messages table if it doesn't exist within message_db, with id, handle, and message
cursor.execute("CREATE TABLE IF NOT EXISTS messages(id INT, handle TEXT, message TEXT)")
return g.message_db
We’ll be using get_message_db()
to access our messages
table in the following functions.
The insert_message(request) Function
We use this function to insert messages and their handles in the messages
table. The id for each message and handle is the number of rows in the messages
table plus one.
def insert_message(request):
# extract message from form in submit.html
message = request.form["message"]
# extract handle from form in submit.html
handle = request.form["handle"]
cursor = get_message_db().cursor()
# count number of rows in messages table to create id for messages and handles
cursor.execute("SELECT COUNT(*) FROM messages")
number_of_rows = cursor.fetchone()
# insert message and handle into messages table, making id one plus number of rows in message table
cursor.execute("INSERT INTO messages(id, handle, message) VALUES(" + str(number_of_rows[0] + 1) + ", \"" + handle + "\", \"" + message + "\")")
get_message_db().commit()
get_message_db().close()
We’ll use this function once the request method from our submit.html
becomes POST
(e.g. when a user submits a message and handle).
The random_messages(n) Function
Again, we use SQL and extract n
random messages to return.
def random_messages(n):
cursor = get_message_db().cursor()
# select random n rows from messages table
cursor.execute("SELECT * FROM messages ORDER BY RANDOM() LIMIT " + str(n))
# fetch n random messages and handles
random_messages = cursor.fetchall()
get_message_db().close()
return random_messages
We pass random_messages(n)
to our view.html
file to display if the user has submitted messages.
The main() Function
The main()
function renders base.html
, the base page of our website.
@app.route("/")
def main():
return render_template("base.html")
The submit() Function
The submit()
function renders submit.html
, which contains input fields for users to input their message and their handle. If the request method is POST
, which occurs when a user has submitted a message and handle, the website will display a message thanking the user for their submission; otherwise the page displays two blank fields and a submit button.
@app.route("/submit/", methods = ["POST", "GET"])
def submit():
# if no message and handle are submitted, display submit.html
if request.method == "GET":
return render_template("submit.html")
else:
# if message and handle are submitted, display submit.html with a thank you message
try:
insert_message(request)
return render_template("submit.html", thanks = True)
except:
return render_template("submit.html")
The view() Function
The view()
function renders view.html
, which displays five randomly chosen messages.
@app.route("/view/")
def view():
# Displays five random messages on view.html
return render_template("view.html", random_messages = random_messages(5))
The base.html File
The base.html
file displays the title and description of our site, as well as two links to submit a message and to view messages that were submitted.
<!doctype html>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<!-- Title -->
<title>A Simple Message Bank</title>
<nav>
<h1>A Simple Message Bank</h1>
<!-- Description -->
<h5>An unapologetically simple message bank. Submit a message, and click "View messages" to view five random messages you've submitted!</h5>
<ul>
<!-- Link to submit a message -->
<li><a href="{{ url_for('submit') }}">Submit a message</a></li>
<!-- Link to view messages -->
<li><a href="{{ url_for('view') }}">View messages</a></li>
</ul>
</nav>
<section class="content">
<header>
{% block header %}{% endblock %}
</header>
{% block content %}{% endblock %}
</section>
The submit.html File
The submit.html
file displays base.html
, as well as two boxes to submit a message and a handle.
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Submit a message{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
<label for="message">Your message:</label>
<br>
<!-- Message submission -->
<input name="message" id="message">
<br>
<label for="handle">Your name or handle:</label>
<br>
<!-- Handle submission -->
<input name="handle" id="handle">
<br>
<!-- Submit button -->
<input type="submit" value="Submit message">
</form>
<!-- Thank you message -->
{% if thanks %}
Thank you for your submission!
{% endif %}
{% endblock %}
The view.html File
The view.html
file displays base.html
, as well as five random messages.
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}View messages{% endblock %}</h1>
{% endblock %}
{% block content %}
<!-- If random messages were queried from database -->
{% if random_messages %}
<!-- For each tuple in random messages -->
{% for tuple in random_messages %}
<br>
<!-- Message -->
"{{tuple[2]}}"
<br>
<!-- Handle -->
- <i>{{tuple[1]}}</i>
<br>
{% endfor %}
{% endif %}
{% endblock %}
Screencaps
Below are some screencaps of the web app in action.
A user submitting a message.
A user viewing submitted messages.