The Way To Make An Internet Utility Using Flask In Python 3 Digitalocean

The author selected the Free and Open Source Fund to get hold of a donation as part of the Write for DOnations program.


Flask is a small and lightweight Python internet framework that gives useful tools and features that make creating internet packages in Python less difficult. It gives builders flexibility and is a extra handy framework for brand spanking new builders in view that you could build a web software speedy the use of handiest a unmarried Python file. Flask is likewise extensible and doesn’t force a selected directory shape or require complicated boilerplate code before getting began.

As part of this educational, you’ll use the Bootstrap toolkit to style your utility so it is more visually appealing. Bootstrap will assist you include responsive web pages to your internet utility so that it additionally works nicely on cell browsers with out writing your personal HTML, CSS, and JavaScript code to reap these desires. The toolkit will will let you attention on mastering how Flask works.

Flask uses the Jinja template engine to dynamically build HTML pages the usage of familiar Python principles together with variables, loops, lists, and so forth. You’ll use those templates as a part of this undertaking.

In this tutorial, you’ll construct a small internet blog the use of Flask and SQLite in Python 3. Users of the utility can view all the posts to your database and click on on the identify of a put up to view its contents with the ability to add a new publish to the database and edit or delete an existing put up.


Before you start following this guide, you will want:

  • A neighborhood Python three programming surroundings, comply with the tutorial in your distribution in How To Install and Set Up a Local Programming Environment for Python 3 series for your local device. In this tutorial we’ll name our venture directory flask_blog.
  • An knowledge of Python three principles, along with statistics kinds, conditional statements, for loops, features, and different such ideas. If you aren’t acquainted with Python, test out our How To Code in Python 3 series.

Step 1 — Installing Flask

In this step, you’ll spark off your Python environment and set up Flask the usage of the pip package installer.

If you haven’t already activated your programming environment, make certain you’re to your task directory (flask_blog) and use the subsequent command to set off the surroundings:

  • supply env/bin/activate

Once your programming surroundings is activated, your set off will now have an env prefix which could look as follows:

This prefix is an indication that the surroundings env is currently lively, which might have another call depending on how you named it throughout advent.

Note: You can use Git, a version manage gadget, to efficaciously manage and track the development technique on your venture. To discover ways to use Git, you may want to check out our Introduction to Git Installation Usage and Branches article.

If you’re using Git, it is a superb idea to ignore the newly created env directory on your .gitignore report to keep away from tracking files no longer associated with the mission.

Now you’ll install Python applications and isolate your venture code faraway from the principle Python gadget set up. You’ll try this using pip and python.

To set up Flask, run the following command:

  • pip deploy flask

Once the set up is whole, run the subsequent command to verify the set up:

  • python -c "import flask; print(flask.__version__)"

You use the python command line interface with the choice -c to execute Python code. Next you import the flask package with import flask; then print the Flask version, which is provided through the flask.__version__ variable.

The output will be a version quantity just like the following:



You’ve created the undertaking folder, a virtual surroundings, and hooked up Flask. You’re now geared up to transport directly to setting up your base utility.

Step 2 — Creating a Base Application

Now that you have your programming environment set up, you’ll start the use of Flask. In this step, you’ll make a small net software inner a Python report and run it to begin the server, so one can show a few records on the browser.

In your flask_blog listing, open a document named for editing, use nano or your preferred text editor:

  • nano hi

This file will function a minimal instance of a way to manage HTTP requests. Inside it, you’ll import the Flask item, and create a function that returns an HTTP response. Write the subsequent code interior good


from flask import Flaskapp = Flask(__name__)@app.path('/')

def hiya():go back 'Hello, World!'

In the previous code block, you first import the Flask object from the flask bundle. You then use it to create your Flask software example with the call app. You bypass the special variable __name__ that holds the call of the modern-day Python module. It’s used to inform the instance where it’s located—you need this because Flask sets up a few paths behind the curtain.

Once you create the app example, you use it to address incoming net requests and send responses to the person. @app.direction is a decorator that turns a everyday Python feature right into a Flask view characteristic, which converts the function’s return cost into an HTTP reaction to be displayed by means of an HTTP purchaser, consisting of a web browser. You bypass the fee ‘/’ to @app.path() to signify that this characteristic will respond to net requests for the URL /, which is the main URL.

The howdy() view function returns the string ‘Hello, World!’ as a response.

Save and near the report.

To run your internet software, you’ll first tell Flask in which to discover the software (the document for your case) with the FLASK_APP environment variable:

  • export FLASK_APP=good day

Then run it in improvement mode with the FLASK_ENV environment variable:

  • export FLASK_ENV=improvement

Lastly, run the utility the use of the flask run command:

  • flask run

Once the utility is going for walks the output may be something like this:


* Serving Flask app "howdy" (lazy loading)* Environment: improvement* Debug mode: on* Running on (Press CTRL+C to cease)* Restarting with stat* Debugger is active!* Debugger PIN: 813-894-335

The preceding output has several portions of statistics, consisting of:

  • The call of the utility you’re going for walks.
  • The surroundings wherein the utility is being run.
  • Debug mode: on means that the Flask debugger is going for walks. This is beneficial whilst developing as it offers us distinctive mistakes messages when things cross incorrect, which makes troubleshooting less complicated.
  • The application is walking locally at the URL, is the IP that represents your gadget’s localhost and :5000 is the port wide variety.

Open a browser and type inside the URL, you may receive the string Hello, World! as a reaction, this confirms that your software is efficaciously walking.

Warning Flask makes use of a simple web server to serve our software in a improvement surroundings, which also method that the Flask debugger is running to make catching mistakes simpler. This development server need to no longer be utilized in a production deployment. See the Deployment Options web page at the Flask documentation for greater information, you may additionally take a look at out this Flask deployment tutorial.

You can now leave the development server running in the terminal and open another terminal window. Move into the venture folder in which is located, activate the virtual environment, set the environment variables FLASK_ENV and FLASK_APP, and preserve to the next steps. (These instructions are listed in advance on this step.)

Note: When opening a brand new terminal, it’s far critical to do not forget activating the virtual surroundings and placing the surroundings variables FLASK_ENV and FLASK_APP.

While a Flask software’s improvement server is already strolling, it isn’t viable to run another Flask application with the equal flask run command. This is due to the fact flask run uses the port wide variety 5000 with the aid of default, and once it’s far taken, it becomes unavailable to run some other application on so you would get hold of an mistakes just like the subsequent:


OSError: [Errno ninety eight] Address already in use

To solve this problem, both prevent the server that’s currently walking thru CTRL+C, then run flask run once more, or if you want to run each at the same time, you could pass a unique port range to the -p argument, for instance, to run another application on port 5001 use the following command:

  • flask run -p 5001

You now have a small Flask web utility. You’ve run your application and displayed data on the internet browser. Next, you’ll use HTML documents to your application.

Step 3 — Using HTML templates

Currently your application best shows a simple message without any HTML. Web applications in particular use HTML to display information for the traveler, so you’ll now work on incorporating HTML documents in your app, which can be displayed on the web browser.

Flask provides a render_template() helper function that allows use of the Jinja template engine. This will make handling HTML a lot simpler through writing your HTML code in .html files as well as the usage of common sense in your HTML code. You’ll use these HTML files, (templates) to build all of your software pages, such as the main page wherein you’ll show the current blog posts, the page of the weblog publish, the page where the user can upload a new publish, and so on.

In this step, you’ll create your foremost Flask software in a new document.

First, on your flask_blog directory, use nano or your favourite editor to create and edit your document. This will preserve all of the code you’ll use to create the running a blog application:

  • nano

In this new record, you’ll import the Flask object to create a Flask utility instance as you previously did. You’ll additionally import the render_template() helper feature that lets you render HTML template files that exist inside the templates folder you’re approximately to create. The report may have a unmarried view characteristic in order to be responsible for managing requests to the primary / course. Add the subsequent content:


from flask import Flask, render_templateapp = Flask(__name__)@app.path('/')

def index():return render_template('index.html')

The index() view feature returns the result of calling render_template() with index.html as an issue, this tells render_template() to look for a report called index.html within the templates folder. Both the folder and the report do no longer yet exist, you may get an errors if you had been to run the software at this factor. You’ll run it although so that you’re familiar with this generally encountered exception. You’ll then restoration it by growing the wanted folder and file.

Save and go out the file.

Stop the development server on your different terminal that runs the whats up application with CTRL+C.

Before you run the utility, ensure you efficaciously specify the value for the FLASK_APP surroundings variable, because you’re now not the use of the application howdy:

  • export FLASK_APP=app

  • flask run

Opening the URL for your browser will bring about the debugger page informing you that the index.html template turned into now not discovered. The predominant line within the code that turned into liable for this error may be highlighted. In this situation, it’s far the line return render_template(‘index.html’).

If you click this line, the debugger will reveal extra code so you have more context to help you clear up the hassle.

To fix this error, create a listing called templates inner your flask_blog directory. Then interior it, open a document known as index.html for modifying:

  • mkdir templates

  • nano templates/index.html

Next, add the following HTML code interior index.html:


<!DOCTYPE html>

<html lang="en">

<head><meta charset="UTF-8"><title>FlaskBlog</identify>


<frame><h1>Welcome to FlaskBlog</h1>



Save the report and use your browser to navigate to again, or refresh the web page. This time the browser must display the textual content Welcome to FlaskBlog in an <h1> tag.

In addition to the templates folder, Flask web applications also typically have a static folder for web hosting static documents, which includes CSS documents, JavaScript documents, and snap shots the utility makes use of.

You can create a style.css fashion sheet record to feature CSS in your application. First, create a directory known as static inside your predominant flask_blog listing:

  • mkdir static

Then create any other listing known as css inside the static listing to host .css files. This is usually carried out to organize static files in dedicated folders, as such, JavaScript documents commonly stay interior a directory known as js, pictures are put in a directory referred to as pictures (or img), and so on. The following command will create the css listing inside the static listing:

  • mkdir static/css

Then open a style.css report within the css directory for enhancing:

  • nano static/css/fashion.css

Add the following CSS rule to your fashion.css document:


h1 border: 2px #eee solid;colour: brown;textual content-align: middle;padding: 10px;

The CSS code will upload a border, trade the colour to brown, center the text, and upload a little padding to <h1> tags.

Save and near the document.

Next, open the index.html template report for modifying:

  • nano templates/index.html

You’ll upload a link to the style.css document inside the <head> segment of the index.html template report:


. . .

<head><meta charset="UTF-8"><hyperlink rel="stylesheet" href=" url_for('static', filename= 'css/fashion.css') "><identify>FlaskBlog</title>


. . .

Here you use the url_for() helper characteristic to generate the right region of the record. The first argument specifies that you’re linking to a static file and the second argument is the route of the document within the static listing.

Save and close the document.

Upon refreshing the index page of your application, you’ll word that the text Welcome to FlaskBlog is now in brown, focused, and enclosed inner a border.

You can use the CSS language to style the utility and make it greater appealing the usage of your personal layout. However, in case you’re now not an internet clothier, or in case you aren’t acquainted with CSS, then you can use the Bootstrap toolkit, which provides smooth-to-use components for styling your application. In this mission, we’ll use Bootstrap.

You would possibly have guessed that making another HTML template might imply repeating maximum of the HTML code you already wrote in the index.html template. You can avoid needless code repetition with the help of a base template file, which all your HTML documents will inherit from. See Template Inheritance in Jinja for extra information.

To make a base template, first create a file called base.html inside your templates listing:

  • nano templates/base.html

Type the following code for your base.html template:


<!doctype html>

<html lang="en"><head><!-- Required meta tags --><meta charset="utf-8"><meta call="viewport" content="width=device-width, preliminary-scale=1, shrink-to-suit=no"><!-- Bootstrap CSS --><link rel="stylesheet" href="" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"><title>% block name % % endblock %</title></head><body><nav magnificence="navbar navbar-make bigger-md navbar-mild bg-light"><a category="navbar-brand" href=" url_for('index')">FlaskBlog</a><button magnificence="navbar-toggler" type="button" records-toggle="fall apart" information-goal="#navbarNav" aria-controls="navbarNav" aria-extended="false" aria-label="Toggle navigation"><span elegance="navbar-toggler-icon"></span></button><div elegance="fall apart navbar-fall apart" identity="navbarNav"><ul magnificence="navbar-nav"><li magnificence="nav-object active"><a class="nav-link" href="#">About</a></li></ul></div></nav><div class="box">% block content % % endblock %</div><!-- Optional JavaScript --><!-- jQuery first, then Popper.js, then Bootstrap JS --><script src="" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="nameless"></script><script src="" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script><script src="" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="nameless"></script></frame>


Save and near the file after you’re done enhancing it.

Most of the code inside the previous block is popular HTML and code required for Bootstrap. The <meta> tags offer facts for the net browser, the <link> tag hyperlinks the Bootstrap CSS documents, and the <script> tags are links to JavaScript code that allows a few additional Bootstrap features, take a look at out the Bootstrap documentation for greater.

However, the subsequent highlighted elements are specific to the Jinja template engine:

  • % block title % % endblock %: A block that serves as a placeholder for a identify, you’ll later use it in other templates to provide a custom name for every web page for your application with out rewriting the entire <head> section whenever.
  • url_for(‘index’): A characteristic call so as to return the URL for the index() view feature. This isn’t like the past url_for() call you used to link a static CSS report, as it best takes one argument, which is the view feature’s call, and hyperlinks to the path associated with the feature rather than a static report.
  • % block content % % endblock %: Another block so as to be replaced by means of content material depending on the child template (templates that inherit from base.html) so one can override it.

Now which you have a base template, you could take benefit of it using inheritance. Open the index.html file:

  • nano templates/index.html

Then update its contents with the subsequent:


% extends 'base.html' %% block content %<h1>% block title % Welcome to FlaskBlog % endblock %</h1>

% endblock %

In this new edition of the index.html template, you use the % extends % tag to inherit from the bottom.html template. You then expand it via changing the content block within the base template with what is in the content block within the previous code block.

This content material block contains an <h1> tag with the text Welcome to FlaskBlog inner a name block, which in flip replaces the original identify block inside the base.html template with the text Welcome to FlaskBlog. This manner, you may keep away from repeating the identical text twice, because it works both as a identify for the web page and a heading that looks beneath the navigation bar inherited from the bottom template.

Template inheritance additionally offers you the capability to reuse the HTML code you have in different templates (base.html in this case) without having to repeat it every time it’s miles wanted.

Save and close the file and refresh the index page in your browser. You’ll see your web page with a navigation bar and styled name.

You’ve used HTML templates and static files in Flask. You extensively utilized Bootstrap to begin refining the look of your web page and a base template to keep away from code repetition. In the following step, you’ll installation a database so as to store your utility statistics.

Step 4 — Setting up the Database

In this step, you’ll set up a database to shop data, that is, the blog posts to your software. You’ll also populate the database with a few instance entries.

You’ll use a SQLite database report to store your data due to the fact the sqlite3 module, which we can use to engage with the database, is comfortably available in the general Python library. For extra facts approximately SQLite, take a look at out this educational.

First, due to the fact information in SQLite is stored in tables and columns, and for the reason that your records specially consists of weblog posts, you first want to create a desk known as posts with the vital columns. You’ll create a .sq. document that carries SQL instructions to create the posts desk with some columns. You’ll then use this report to create the database.

Open a report known as schema.sq. inner your flask_blog listing:

  • nano schema.square

Type the subsequent SQL commands interior this record:




Save and near the document.

The first SQL command is DROP TABLE IF EXISTS posts;, this deletes any already current tables named posts so that you don’t get confusing conduct. Note that this will delete all the content material you’ve got inside the database on every occasion you operate these SQL commands, so make sure you don’t write any critical content inside the web utility till you end this academic and test with the final end result. Next, CREATE TABLE posts is used to create the posts table with the subsequent columns:

  • identification: An integer that represents a number one key, this could get assigned a unique fee via the database for each entry (that may be a weblog put up).
  • created: The time the blog post become created at. NOT NULL means that this column should not be empty and the DEFAULT fee is the CURRENT_TIMESTAMP value, that is the time at which the publish turned into added to the database. Just like identification, you don’t want to specify a fee for this column, because it will be automatically stuffed in.
  • identify: The publish identify.
  • content: The put up content material.

Now that you have a SQL schema in the schema.square file, you’ll use it to create the database the use of a Python file to be able to generate an SQLite .db database file. Open a document named within the flask_blog listing using your chosen editor:

  • nano

And then upload the subsequent code.


import sqlite3connection = sqlite3.join('database.db')with open('schema.sq.') as f:connection.executescript(f.examine())cur = connection.cursor()cur.execute("INSERT INTO posts (identify, content) VALUES (?, ?)",('First Post', 'Content for the first publish'))cur.execute("INSERT INTO posts (name, content material) VALUES (?, ?)",('Second Post', 'Content for the second one submit'))connection.devote()


You first import the sqlite3 module and then open a connection to a database file named database.db, on the way to be created when you run the Python file. Then you operate the open() feature to open the schema.square file. Next you execute its contents using the executescript() technique that executes multiple SQL statements without delay, in order to create the posts desk. You create a Cursor item that lets in you to use its execute() technique to execute two INSERT SQL statements to feature weblog posts for your posts desk. Finally, you commit the changes and close the connection.

Save and close the file after which run it in the terminal the use of the python command:

  • python

Once the document finishes execution, a new report called database.db will appear for your flask_blog listing. This way you’ve successfully installation your database.

In the subsequent step, you’ll retrieve the posts you inserted into your database and display them for your application’s homepage.

Step 5 — Displaying All Posts

Now which you’ve installation your database, you may now alter the index() view characteristic to display all the posts you’ve got for your database.

Open the file to make the following modifications:

  • nano

For your first change, you’ll import the sqlite3 module at the pinnacle of the file:


import sqlite3

from flask import Flask, render_template. . .

Next, you’ll create a function that creates a database connection and return it. Add it without delay after the imports:


. . .

from flask import Flask, render_templatedef get_db_connection():conn = sqlite3.join('database.db')conn.row_factory = sqlite3.Rowreturn conn. . .

This get_db_connection() function opens a connection to the database.db database record, and then units the row_factory characteristic to sqlite3.Row so you will have name-based totally get right of entry to to columns. This manner that the database connection will return rows that behave like regular Python dictionaries. Lastly, the characteristic returns the conn connection item you’ll be the use of to get entry to the database.

After defining the get_db_connection() characteristic, alter the index() feature to look like the following:


. . .@app.direction('/')

def index():conn = get_db_connection()posts = conn.execute('SELECT * FROM posts').fetchall()conn.close()return render_template('index.html', posts=posts)

In this new version of the index() function, you first open a database connection using the get_db_connection() feature you defined in advance. Then you execute an SQL query to pick out all entries from the posts table. You put into effect the fetchall() method to fetch all the rows of the query end result, this could return a list of the posts you inserted into the database inside the preceding step.

You near the database connection the usage of the near() method and return the end result of rendering the index.html template. You additionally pass the posts item as an issue, which contains the results you bought from the database, this will allow you to get entry to the weblog posts within the index.html template.

With those changes in area, shop and close the report.

Now that you’ve passed the posts you fetched from the database to the index.html template, you can use a for loop to display every put up on your index page.

Open the index.html record:

  • nano templates/index.html

Then, alter it to appearance as follows:


% extends 'base.html' %% block content %<h1>% block identify % Welcome to FlaskBlog % endblock %</h1>% for put up in posts %<a href="#"><h2> post['identify'] </h2></a><span class="badge badge-number one"> submit['created'] </span><hr>% endfor %

% endblock %

Here, the syntax % for submit in posts % is a Jinja for loop, that is just like a Python for loop except that it must be later closed with the % endfor % syntax. You use this syntax to loop over each object in the posts list that turned into exceeded by using the index() feature inside the line return render_template(‘index.html’, posts=posts). Inside this for loop, you show the publish name in an <h2> heading internal an <a> tag (you’ll later use this tag to hyperlink to each post individually).

You show the name using a literal variable delimiter ( … ). Remember that publish might be a dictionary-like object, so that you can get right of entry to the publish name with publish[‘name’]. You additionally display the submit advent date the use of the same technique.

Once you are executed editing the record, store and near it. Then navigate to the index page in your browser. You’ll see the 2 posts you added to the database on your page.

Now which you’ve changed the index() view function to show all the posts you’ve got within the database in your utility’s homepage, you’ll circulate directly to show each post in a single page and allow users to link to each person publish.

Step 6 — Displaying a Single Post

In this step, you’ll create a new Flask course with a view function and a new HTML template to display an man or woman blog publish by its ID.

By the cease of this step, the URL will be a web page that displays the first put up (as it has the ID 1). The URL will show the submit with the associated ID variety if it exists.

Open for editing:

  • nano

Since you’ll need to get a blog put up by means of its ID from the database in multiple locations later in this assignment, you’ll create a standalone characteristic called get_post(). You can call it by passing it an ID and get hold of back the blog submit related to the furnished ID, or make Flask respond with a 404 Not Found message if the weblog publish does not exist.

To reply with a 404 page, you need to import the abort() characteristic from the Werkzeug library, which changed into hooked up along with Flask, at the pinnacle of the file:


import sqlite3

from flask import Flask, render_template

from werkzeug.exceptions import abort. . .

Then, upload the get_post() feature right after the get_db_connection() function you created inside the previous step:


. . .def get_db_connection():conn = sqlite3.connect('database.db')conn.row_factory = sqlite3.Rowreturn conndef get_post(post_id):conn = get_db_connection()publish = conn.execute('SELECT * FROM posts WHERE identity = ?',(post_id,)).fetchone()conn.close()if publish is None:abort(404)return publish. . .

This new function has a post_id argument that determines what blog put up to go back.

Inside the function, you use the get_db_connection() function to open a database connection and execute a SQL query to get the weblog put up related to the given post_id price. You upload the fetchone() technique to get the result and keep it within the post variable then near the connection. If the put up variable has the price None, meaning no result was discovered in the database, you operate the abort() function you imported in advance to reply with a 404 blunders code and the function will finish execution. If but, a post became determined, you come the fee of the put up variable.

Next, add the following view function at the cease of the record:


. . .@app.route('/<int:post_id>')

def publish(post_id):submit = get_post(post_id)return render_template('publish.html', put up=post)

In this new view feature, you add a variable rule <int:post_id> to specify that the component after the scale back (/) is a high-quality integer (marked with the int converter) that you want to get admission to for your view characteristic. Flask recognizes this and passes its fee to the post_id key-word argument of your put up() view feature. You then use the get_post() characteristic to get the weblog publish associated with the required ID and shop the result in the post variable, which you pass to a put up.html template that you’ll quickly create.

Save the file and open a new publish.html template record for modifying:

  • nano templates/post.html

Type the following code on this new submit.html record. This will be much like the index.html document, except that it’s going to simplest display a single put up, in addition to additionally showing the contents of the put up:


% extends 'base.html' %% block content %<h2>% block name %  put up['title']  % endblock %</h2><span elegance="badge badge-number one"> put up['created'] </span><p> post['content'] </p>

% endblock %

You upload the title block which you described inside the base.html template to make the name of the web page mirror the submit title that is displayed in an <h2> heading on the same time.

Save and close the document.

You can now navigate to the subsequent URLs to peer the two posts you’ve got in your database, along with a page that tells the person that the requested blog submit became not discovered (given that there may be no publish with an ID variety of 3 thus far):

Going returned to the index page, you’ll make each publish identify link to its respective web page. You’ll do this using the url_for() feature. First, open the index.html template for editing:

  • nano templates/index.html

Then alternate the price of the href characteristic from # to url_for(‘put up’, post_id=put up[‘id’]) so that the for loop will look precisely as follows:


% for submit in posts %<a href=" url_for('put up', post_id=post['identification']) "><h2> submit['identify'] </h2></a><span class="badge badge-primary"> post['created'] </span><hr>

% endfor %

Here, you skip ‘post’ to the url_for() feature as a first argument. This is the call of the put up() view feature and since it accepts a post_id argument, you give it the fee publish[‘id’]. The url_for() feature will return the proper URL for every put up based totally on its ID.

Save and near the file.

The hyperlinks on the index web page will now feature as anticipated. With this, you’ve now completed building the a part of the application responsible for showing the blog posts in your database. Next, you’ll add the capability to create, edit, and delete weblog posts on your software.

Step 7 — Modifying Posts

Now which you’ve finished showing the weblog posts which are present inside the database on the web software, you want to allow the customers of your utility to write down new blog posts and add them to the database, edit the prevailing ones, and delete pointless weblog posts.

Creating a New Post

Up thus far, you have got an software that presentations the posts to your database but offers no manner of adding a brand new put up except you without delay connect to the SQLite database and upload one manually. In this segment, you’ll create a page on which you will be able to create a put up by means of imparting its identify and content.

Open the record for enhancing:

  • nano

First, you’ll import the following from the Flask framework:

  • The worldwide request item to access incoming request facts on the way to be submitted via an HTML shape.
  • The url_for() characteristic to generate URLs.
  • The flash() characteristic to flash a message when a request is processed.
  • The redirect() feature to redirect the patron to a one-of-a-kind area.

Add the imports for your file like the following:


import sqlite3

from flask import Flask, render_template, request, url_for, flash, redirect

from werkzeug.exceptions import abort. . .

The flash() function stores flashed messages within the client’s browser consultation, which calls for putting a mystery key. This secret secret’s used to steady sessions, which allow Flask to recall records from one request to every other, including moving from the new post web page to the index web page. The user can get entry to the records stored inside the consultation, but can not alter it except they have the name of the game key, so that you must never permit every body to access your mystery key. See the Flask documentation for periods for extra facts.

To set a secret key, you’ll add a SECRET_KEY configuration in your application thru the app.config item. Add it immediately following the app definition before defining the index() view feature:


. . .

app = Flask(__name__)

app.config['SECRET_KEY'] = 'your mystery key'@app.direction('/')

def index():conn = get_db_connection()posts = conn.execute('SELECT * FROM posts').fetchall()conn.near()go back render_template('index.html', posts=posts). . .

Remember that the name of the game key must be a long random string.

After placing a mystery key, you’ll create a view function to be able to render a template that shows a shape you could fill in to create a new weblog publish. Add this new characteristic at the bottom of the file:


. . .@app.course('/create', strategies=('GET', 'POST'))

def create():return render_template('create.html')

This creates a /create route that accepts each GET and POST requests. GET requests are well-known by using default. To also accept POST requests, which might be despatched via the browser while submitting paperwork, you’ll pass a tuple with the widespread styles of requests to the techniques argument of the @app.route() decorator.

Save and near the report.

To create the template, open a file called create.html inner your templates folder:

  • nano templates/create.html

Add the following code inner this new report:


% extends 'base.html' %% block content material %

<h1>% block name % Create a New Post % endblock %</h1><shape technique="publish"><div elegance="shape-organization"><label for="identify">Title</label><input kind="textual content" name="title"placeholder="Post name" magnificence="shape-manipulate"cost=" request.shape['title'] "></enter></div><div elegance="shape-group"><label for="content">Content</label><textarea name="content" placeholder="Post content"elegance="shape-manipulate"> request.shape['content'] </textarea></div><div magnificence="form-institution"><button kind="publish" elegance="btn btn-primary">Submit</button></div>


% endblock %

Most of this code is trendy HTML. It will show an input box for the publish title, a textual content location for the publish content material, and a button to submit the shape.

The cost of the put up name input is request.form[‘name’] and the text area has the value request.form[‘content material’] , this is executed in order that the data you enter does not wander away if something is going incorrect. For example, in case you write a protracted post and you neglect to present it a name, a message will be displayed informing you that the identify is needed. This will occur with out dropping the submit you wrote since it’ll be saved inside the request worldwide item that you have get entry to to on your templates.

Now, with the development server walking, use your browser to navigate to the /create route:

You will see a Create a New Post web page with a container for a name and content.

This shape submits a POST request to your create() view characteristic. However, there’s no code to handle a POST request within the characteristic but, so nothing occurs after filling within the form and submitting it.

You’ll handle the incoming POST request when a form is submitted. You’ll do that inside the create() view function. You can separately deal with the POST request by means of checking the cost of request.approach. When its price is about to ‘POST’ it manner the request is a POST request, you’ll then continue to extract submitted facts, validate it, and insert it into your database.

Open the report for enhancing:

  • nano

Modify the create() view feature to look precisely as follows:


. . .@app.route('/create', methods=('GET', 'POST'))

def create():if request.technique == 'POST':name = request.form['name']content = request.shape['content']if not identify:flash('Title is needed!')else:conn = get_db_connection()conn.execute('INSERT INTO posts (title, content material) VALUES (?, ?)',(name, content))conn.dedicate()conn.close()return redirect(url_for('index'))go back render_template('create.html')

In the if assertion you make certain that the code following it’s miles simplest done whilst the request is a POST request via the assessment request.approach == ‘POST’.

You then extract the submitted name and content material from the request.shape item that gives you get admission to to the form statistics inside the request. If the title isn’t provided, the circumstance if not identify would be fulfilled, displaying a message to the person informing them that the title is needed. If, alternatively, the identify is furnished, you open a connection with the get_db_connection() characteristic and insert the identify and the content material you acquired into the posts desk.

You then commit the adjustments to the database and close the relationship. After adding the weblog post to the database, you redirect the patron to the index page the use of the redirect() characteristic passing it the URL generated by using the url_for() characteristic with the fee ‘index’ as an argument.

Save and close the file.

Now, navigate to the /create route the use of your web browser:

Fill in the form with a name of your desire and a few content material. Once you publish the form, you’ll see the brand new put up listed at the index web page.

Lastly, you’ll display flashed messages and add a link to the navigation bar in the base.html template to have clean get entry to to this new page. Open the template file:

  • nano templates/base.html

Edit the file by way of including a new <li> tag following the About hyperlink within the <nav> tag. Then add a brand new for loop at once above the content material block to display the flashed messages underneath the navigation bar. These messages are to be had inside the special get_flashed_messages() characteristic Flask gives:


<nav class="navbar navbar-make bigger-md navbar-mild bg-light"><a category="navbar-logo" href=" url_for('index')">FlaskBlog</a><button elegance="navbar-toggler" type="button" information-toggle="fall apart" statistics-target="#navbarNav" aria-controls="navbarNav" aria-increased="fake" aria-label="Toggle navigation"><span elegance="navbar-toggler-icon"></span></button><div elegance="crumble navbar-fall apart" identity="navbarNav"><ul elegance="navbar-nav"><li elegance="nav-object"><a class="nav-link" href="#">About</a></li><li magnificence="nav-object"><a category="nav-link" href="url_for('create')">New Post</a></li></ul></div>


<div elegance="field">% for message in get_flashed_messages() %<div magnificence="alert alert-threat"> message </div>% endfor %% block content % % endblock %


Save and near the document. The navigation bar will now have a New Post item that hyperlinks to the /create direction.

Editing a Post

For a blog to be updated, you’ll need as a way to edit your current posts. This section will guide you thru growing a new page for your software to simplify the technique of enhancing a publish.

First, you’ll add a brand new direction to the report. Its view feature will get hold of the ID of the put up that desires to be edited, the URL could be in the layout /post_id/edit with the post_id variable being the ID of the submit. Open the document for modifying:

  • nano

Next, upload the subsequent edit() view characteristic at the quit of the report. Editing an present submit is just like growing a brand new one, so this view characteristic could be similar to the create() view characteristic:


. . .@app.direction('/<int:id>/edit', strategies=('GET', 'POST'))

def edit(identity):post = get_post(identification)if request.method == 'POST':title = request.form['identify']content = request.shape['content']if no longer name:flash('Title is needed!')else:conn = get_db_connection()conn.execute('UPDATE posts SET identify = ?, content = ?'' WHERE identification = ?',(identify, content, identification))conn.devote()conn.near()return redirect(url_for('index'))return render_template('edit.html', publish=put up)

The publish you edit is decided via the URL and Flask will bypass the ID range to the edit() function thru the identity argument. You add this price to the get_post() function to fetch the submit related to the provided ID from the database. The new statistics will come in a POST request, which is dealt with within the if request.approach == ‘POST’ condition.

Just like when you create a new publish, you first extract the information from the request.shape item then flash a message if the name has an empty value, in any other case, you open a database connection. Then you update the posts desk with the aid of placing a brand new name and new content in which the ID of the post inside the database is identical to the ID that become within the URL.

In the case of a GET request, you render an edit.html template passing inside the submit variable that holds the lower back fee of the get_post() characteristic. You’ll use this to display the prevailing name and content at the edit page.

Save and near the file, then create a new edit.html template:

  • nano templates/edit.html

Write the subsequent code interior this new document:


% extends 'base.html' %% block content %

<h1>% block title % Edit " publish['title'] " % endblock %</h1><shape technique="submit"><div magnificence="shape-organization"><label for="identify">Title</label><input kind="textual content" name="identify" placeholder="Post identify"class="form-manage"price=" request.form['identify'] or put up['identify'] "></enter></div><div class="shape-group"><label for="content">Content</label><textarea name="content material" placeholder="Post content material"magnificence="shape-manage"> request.shape['content material'] or submit['content'] </textarea></div><div elegance="shape-group"><button type="post" magnificence="btn btn-primary">Submit</button></div>



% endblock %

Save and near the document.

This code follows the identical sample except for the request.form[‘name’] or put up[‘identify’] and request.form[‘content material’] or publish[‘content material’] syntax. This displays the information saved within the request if it exists, otherwise it displays the records from the post variable that was exceeded to the template containing modern-day database statistics.

Now, navigate to the following URL to edit the primary submit:

You will see an Edit “First Post” web page.

Edit the publish and submit the shape, then make sure the post become updated.

You now want to feature a link that factors to the edit web page for each submit on the index page. Open the index.html template record:

  • nano templates/index.html

Edit the document to appearance exactly just like the following:


% extends 'base.html' %% block content material %<h1>% block identify % Welcome to FlaskBlog % endblock %</h1>% for submit in posts %<a href=" url_for('put up', post_id=submit['identification']) "><h2> put up['identify'] </h2></a><span magnificence="badge badge-number one"> post['created'] </span><a href=" url_for('edit', identity=publish['identity']) "><span class="badge badge-caution">Edit</span></a><hr>% endfor %

% endblock %

Save and close the report.

Here you upload an <a> tag to hyperlink to the edit() view characteristic, passing within the publish[‘identification’] fee to link to the edit page of every put up with the Edit hyperlink.

Deleting a Post

Sometimes a put up no longer wishes to be publicly available, that’s why the capability of deleting a publish is important. In this step you’ll add the delete functionality on your software.

First, you’ll upload a brand new /ID/delete route that accepts POST requests, similar to the edit() view feature. Your new delete() view characteristic will get hold of the ID of the publish to be deleted from the URL. Open the record:

  • nano

Add the following view feature at the lowest of the document:


# ....@app.route('/<int:identification>/delete', techniques=('POST',))

def delete(identity):post = get_post(identity)conn = get_db_connection()conn.execute('DELETE FROM posts WHERE identification = ?', (identity,))conn.devote()conn.close()flash('"" become efficiently deleted!'.layout(put up['identify']))go back redirect(url_for('index'))

This view function handiest accepts POST requests. This method that navigating to the /ID/delete route to your browser will return an error because net browsers default to GET requests.

However you can get admission to this direction via a form that sends a POST request passing in the ID of the post you need to delete. The characteristic will get hold of the ID price and use it to get the submit from the database with the get_post() function.

Then you open a database connection and execute a DELETE FROM SQL command to delete the submit. You dedicate the change to the database and close the connection at the same time as flashing a message to inform the user that the publish turned into efficiently deleted and redirect them to the index page.

Note which you don’t render a template file, this is because you’ll just add a Delete button to the edit web page.

Open the edit.html template document:

  • nano templates/edit.html

Then upload the subsequent <shape> tag after the <hr> tag and without delay before the % endblock % line:


<hr><form movement=" url_for('delete', identification=publish['identification']) " approach="POST"><input kind="post" fee="Delete Post"magnificence="btn btn-hazard btn-sm"onclick="return verify('Are you positive you want to delete this submit?')">

</form>% endblock %

You use the verify() method to display a affirmation message earlier than submitting the request.

Now navigate again to the edit page of a blog publish and attempt deleting it:

At the cease of this step, the source code of your challenge will appear to be the code on this web page.

With this, the users of your utility can now write new blog posts and upload them to the database, edit, and delete existing posts.


This educational introduced important principles of the Flask Python framework. You found out how to make a small web software, run it in a development server, and allow the consumer to provide custom statistics through URL parameters and net bureaucracy. You also used the Jinja template engine to reuse HTML files and use logic in them. At the give up of this tutorial, you now have a totally functioning web blog that interacts with an SQLite database to create, show, edit, and delete weblog posts the use of the Python language and SQL queries. If you would really like to research greater approximately working with Flask and SQLite test out this tutorial on How To Use One-to-Many Database Relationships with Flask and SQLite.

You can in addition expand this application through adding consumer authentication so that handiest registered customers can create and modify weblog posts, you may additionally upload remarks and tags for each blog put up, and upload file uploads to give users the ability to consist of snap shots inside the publish. See the Flask documentation for more data.

Flask has many community-made Flask extensions. The following is a listing of extensions you may recollect using to make your improvement process easier:

  • Flask-Login: manages the user session and handles logging in and logging out and remembering logged-in customers.
  • Flask-SQLAlchemy: simplifies the usage of Flask with SQLAlchemy, a Python SQL toolkit and Object Relational Mapper for interacting with SQL databases.
  • Flask-Mail: enables with the venture of sending email messages on your Flask utility.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *