Flask vs. Django: Why Flask Might Be Better
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.
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.
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__) def hello(): return "Hello, World!" if __name__ == "__main__": app.run()
Let's break down what this code does:
- Line 1 imports Flask
- Line 3 initializes an
appvariable, using the
- Line 5 is where the magic of Flask happens. The
@app.routeis 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.routecalls, 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
hellois 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.
- Line 9 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
appwe 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:
http://127.0.0.1:5000/ (Press CTRL+C to quit)> Running on
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 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
HttpResponsefunction, 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.pyfiles — 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
urlfunction so that we can link specific URLs to functions in our
- Line 3 imports the
views.pyfile that we added our "Hello, World"
- Lines 5-7 sets up a list of
urlpatterns— this is equivalent to the
@app.routedecorators that we used in Flask. We match specific URLs using regular expressions, and link these to functions in our
views.pyscript. 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.indexfunction 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).
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.