Flask and Django are two of the most popular web frameworks for Python (although there are many more). In this post, I'll discuss some of the points you should consider when you're choosing between Flask and Django. We'll also walk through a "Hello, World" app in each of them to get more of a hands-on feel for how they work.

(Note: I'm a long-time Flask user and author of the book Flask by Example, so I'm personally a bit biased towards Flask. I'll keep this overview as objective as possible though).

Wait, why do I need a web framework and what is it anyway.

When you first started developing Python applications, you probably developed so-called "command line applications". The user has to run these scripts in a shell or command prompt and pass input as arguments or through standard input. Several years ago, the natural progression from building these kind of applications was to build desktop applications — a program that allows users to interact using a mouse and keyboard, which contains menus and other interactive elements. These days, it's more common to transition into building web applications — your users will interact with your program via their web browser. For a nice overview of why web applications are arguably better than desktop applications, see Patrick "patio11" McKenzie's post here: http://www.kalzumeus.com/2009/09/05/desktop-aps-versus-web-apps/.

If you decide you want to build a web application, and you would like to develop it in Python, you'll probably want a so-called web framework. There are a lot of repetitive and boring parts of building backend logic, user interface, and hooking everything up to the Internet so that users can navigate your app in their browser. A web framework aims to implement all the functionality common to most web applications, such as mapping URLs to chunks of Python code.

Exactly what is implemented in the framework and what is left for the application developer to write varies from framework to framework. The biggest difference between Flask and Django is:

Flask implements a bare-minimum and leaves the bells and whistles to add-ons or to the developer

Django follows a "batteries included" philosophy and gives you a lot more out of the box.

We will now discuss their differences in more detail.

Quick Comparison

If you're here for quick answers, this section is for you!

Main contrasts: Flask provides simplicity, flexibility and fine-grained control. It is unopinionated (it lets you decide how you want to implement things). Django provides an all-inclusive experience: you get an admin panel, database interfaces, an ORM, and directory structure for your apps and projects out of the box.

You should probably choose: Flask, if you're focused on the experience and learning opportunities, or if you want more control about which components to use (such as what databases you want to use and how you want to interact with them). Django, if you're focused on the final product. Especially if you're working on a straight-forward application such as a news site, an e-store, or blog, and you want there to always be a single, obvious way of doing things.

More information: Django has been around for longer — it was first released in 2005, while Flask debuted in 2010 — and is more popular — in January 2017, there were 2631 StackOverflow questions about Django and 575 for Flask. Both frameworks are growing steadily in popularity, as can be seen by the number of StackOverflow questions about each in the image below.

Flask has a much lighter footprint, comprising under 10000 source lines of code to Django's approximately 240000 lines.



The first thing people usually do when they're learning a new technology is to follow the simplest set of steps that produces the output "Hello, World!" Below, we will go over the steps to build a "Hello World" applications with Flask and Django.

Note that Flask, which is focused on simplicity and minimalism, allows us to get "Hello World" running much faster, but this should not be taken to mean that Flask is the superior framework. It would probably take less time and effort to get a more sophisticated web application (such as one that handles and validates user input and stores this in a database) running in Django than in Flask. However, seeing the two Hello World projects will give us a better feel for the two frameworks, and it will allow us to describe some of their inner workings along the way.

Flask

The first thing we need to do in order to use Flask is to install it. This can easily be done by using pip . Depending on how your pip is set up, and which version of Python you usually use, you may not need the 3 or the --user flag in the command below.

pip3 install flask --user

Once you've done that, create a Python file called flaskhello.py and insert the following code:

from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello, World!" if __name__ == "__main__": app.run()

Let's break down what this code does:

Line 1 imports Flask

imports Flask Line 3 initializes an app variable, using the __name__ attribute

initializes an variable, using the attribute Line 5 is where the magic of Flask happens. The @app.route is a Python decorator. It takes the function directly below it and modifies it. In this case, we use this to route traffic from a specific URL to the function directly below. Using different @app.route calls, we can 'trigger' different parts of the code when the user visits different parts of our application. In this case, we only have a single route / , which is the default "root" of our application.

is where the magic of Flask happens. The is a Python decorator. It takes the function directly below it and modifies it. In this case, we use this to route traffic from a specific URL to the function directly below. Using different calls, we can 'trigger' different parts of the code when the user visits different parts of our application. In this case, we only have a single route , which is the default "root" of our application. In Line 6 the function name hello is not important. In stead of calling this function from somewhere else in our code, it will be called automatically. It's still a good practice to give it a relevant name though.

the function name is not important. In stead of calling this function from somewhere else in our code, it will be called automatically. It's still a good practice to give it a relevant name though. Line 7 returns the string to our user. Usually we would render a template or return HTML here so that users will see a nicely formatted page, but returning a Python string works fine too.

returns the string to our user. Usually we would render a template or return HTML here so that users will see a nicely formatted page, but returning a Python string works fine too. Line 9 is normal Python boilerplate to make sure we don't run anything automatically if our code is imported by another Python script.

is normal Python boilerplate to make sure we don't run anything automatically if our code is imported by another Python script. Line 10 calls the run() method of the app we initialized in Line 3. This starts the development server for Flask and allows us to visit our web application from our local machine by visiting localhost.

You can now run the command python3 flaskhello.py and you should see output similar to:

>>> Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

In the message above, '5000' is the port number that our Application is running on (yours might be different, e.g. '5003') and '127.0.0.1' means that the application is running on local host — it's only accessible on our development machine. If you open a web browser and visit http://127.0.0.1:5000/ (substituting the port number if necessary), you'll see a web page that returns the "Hello, World!" greeting.

Django

Django can also be installed through pip . Run the following command:

pip3 install django --user

Once it's installed, we need to run some Django scripts to create a project in order to create an app. When you installed Django, it also set up the django-admin command, which we'll use now. Run the following:

django-admin startproject hellodjango

This creates a new Django "project," and will create the hellodjango directory in the location where you ran the command. If you look in the hellodjango directory, you'll see that it created a manage.py file and a subdirectory which is also called hellodjango . Inside the subdirectory there are three Python scripts. We'll only need to worry about urls.py for our "Hello World" project.

The next step is to use Django to create an App, which is an organizational structure below that of a Django Project (one Project can contain many apps). We will use the manage.py file that the previous command created in order to create the application. From the outer hellodjango directory, run the following command:

python3 manage.py startapp helloworld

This creates the helloworld app and makes it part of our hellodjango project. Now we need to configure the URL routing (like we did with @app.route in Flask). Because Django projects have more default structure than Flask apps, we'll have a few extra steps. The previous command created a helloworld directory within the outer hellodjango directory. Open the automatically created helloworld/views.py file and add the following code:

from django.http import HttpResponse def index(request): return HttpResponse("Hello, World!")

Line 1 imports the HttpResponse function, which we can use to send a string over HTTP to the user of our web app. As with Flask, we wouldn't usually use this, as we'd want to do more complicated things with rendering HTML templates. However, for our Hello World app this is all we need.

imports the function, which we can use to send a string over HTTP to the user of our web app. As with Flask, we wouldn't usually use this, as we'd want to do more complicated things with rendering HTML templates. However, for our Hello World app this is all we need. In line 3 , we're defining an index function. Here, unlike with Flask, we don't use a decorator that says this function should be called when the user visits our application. Instead, we'll set this up via two urls.py files — one for the project, which was automatically created, and one for the application, which we'll need to create.

, we're defining an index function. Here, unlike with Flask, we don't use a decorator that says this function should be called when the user visits our application. Instead, we'll set this up via two files — one for the project, which was automatically created, and one for the application, which we'll need to create. Line 4 returns the "Hello, World!" string wrapped in an HttpResponse so that it can be displayed in our user's web browser.

Now we need to create a urls.py file for our application. Create helloworld/urls.py and add the following code:

from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index, name='index'), ]

Line 1 imports the url function so that we can link specific URLs to functions in our views.py file.

imports the function so that we can link specific URLs to functions in our file. Line 3 imports the views.py file that we added our "Hello, World" index() view to.

imports the file that we added our "Hello, World" view to. Lines 5-7 sets up a list of urlpatterns — this is equivalent to the @app.route decorators that we used in Flask. We match specific URLs using regular expressions, and link these to functions in our views.py script. In this case, we set up a single pattern, which matches an empty URL (like "/" in Flask — in other words, the default page of our application) and links it to the views.index function that we wrote earlier.

That's the URL configuration for our app ( helloworld ). We also need a URL configuration for our project ( hellodjango ). Edit the hellodjango/hellodjango/urls.py file, which was automatically created (it might be a bit confusing that there are two urls.py files, but it should make sense if you think of one belonging to the entire project, routing URLs to different apps, and the other belonging to the helloworld app alone). Add the following code:

from django.conf.urls import include, url urlpatterns = [ url(r'^hello/', include('helloworld.urls')), ]

This is similar to the previous file. However, instead of routing URLs of a specific pattern to a specific view, we are routing them to a specific application. In this case, any URL that has /hello after it will be sent along to our helloworld application and will look in helloworld.urls to work out which view to call.

Now go back to the outer /hellodjango directory (the one which contains the manage.py file) and run the following command:

python3 manage.py runserver

This runs the Django development server, which lets us visit our application on localhost, as we did with Flask. You should see output that is similar to the following:

Performing system checks... System check identified no issues (0 silenced). You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. February 03, 2017 - 16:14:20 Django version 1.10.5, using settings 'hellodjango.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.

You can ignore the warning about the migrations — this is related to the database for the web application, which we are not using. The important line is line 10, which, similarly to Flask, tells you which port the server is running on. In the example above, it is 8000, so we can visit http://127.0.0.1:8000/hello to view our "Hello, World!" greeting (don't forget the /hello at the end, which tells Django which app to visit).

Final Remarks

In this post, I provided an introduction to Flask and Django, followed by a short comparison of the two, and then proceeded to show how to build a "Hello World" app using each framework.

Django is a heavier framework than Flask — if you're learning web programming, it can be harder to figure out which pieces are responsible for what functionality, and what you need to change to get the results that you want. However, once you get used to Django, the extra work it does can be really useful and can save you time in setting up repetitive, boring components of a web application.

It's sometimes difficult to choose between the two frameworks — the nice thing is that even when you get into their more advanced functionality, such as templates, the two remain very similar in many aspects (many job advertisements ask for "Django or Flask experience" as a result). It's therefore easy to switch from one to the other if you ever need to or want to.

If you're still in doubt as to which framework to use after reading this guide, I would recommend that you go with Flask — you'll figure out how the pieces fit together more easily, and you'll never have functionality lying around that you're not actually using.