Category
Artificial Intelligence
Web

Flask vs Django: A Comparative Guide to Python Frameworks

Our study of two of the most prestigious Python-based web frameworks compares and contrasts the very different approaches each takes and the factors favoring one over the other.

A web framework provides developers with at least a subset of the essential tools and features necessary to create, develop and maintain new projects, including AI development, without either inventing these facilities from scratch or requiring excessive effort to integrate third-party libraries that might fill in the missing traits.

Python-based web frameworks are currently among the most popular, both because of the general rise of Python as a programming language and the specific boost that the new wave of GPU-based machine learning and analytics research has given to the Python developer base over the last ten years.

In this article, we'll examine and compare the merits of two of the most popular Python-based web frameworks, Flask and Django.

Flask or Django? Here's the ultimate head-to-head guide to these Python frameworks
Tweet

The Distinct Virtues of David and Goliath

The extent to which a framework anticipates your project's requirements will dictate the scope of its feature set. The more eventualities a framework caters to, the quicker it can help you bring your project to market.

However, such a comprehensive facility for rapid prototyping often comes with more than one cost. These can include:

  • Framework overhead, wherein the complexity of the architecture and the number of redundant features can impede overall performance (a problem that can become notable at scale).
  • More maintenance needed, because changes to secondary modules may have knock-on effects on the general architecture, even when modules are integrated rather than third-party.
  • A greater attack surface, when unnecessary and unused code remains public-facing.
  • Brittle builds, wherein intra-dependencies of the central architecture are so complex that it can prove difficult or burdensome to incorporate essential external code (i.e. extensions or third-party libraries)

A 'lighter' web framework poses few, if any, of these challenges. It will not usually impede the development of any desired extra features, will generally be optimized for further development (i.e. having established API routes and third-party extensions), and will tend to perform faster.

Notwithstanding, a 'minimalist' web framework of this type may present other issues:

  • Lack of essential functionality, giving you—by default—a lean and fast deployment that doesn’t do all the things you need it to.
  • Increased development time and costs, since you must choose, integrate and implement third-party solutions or expensive original code in order to obtain necessary features.
  • Increased possibility of security issues, via custom-built security workflows and the necessity for third-party code to provide non-bundled functionality.
  • Decreased access to community solutions, since your extended build is likely to have case-specific dependencies, where any errors may not be catered to by a community that is used to dealing with the core codebase and more common issues.

Flask is our 'David', Django our 'Goliath'. Nonetheless, the outcome of the battle is anything but certain, because the two frameworks cater to two different use cases, where ease of implementation is played off against framework overhead.

Origins and Uptake

Flask

CREATED:
2010
LICENSE:
BSD-3
HOME SITE:
https://palletsprojects.com/p/flask/
GITHUB:
https://github.com/pallets/flask
FORKS:
12,870
STARS:
45,761
USED BY:
300,700 projects
STACK OVERFLOW QUESTIONS:
29,378
NOTABLE CUSTOMERS:
LinkedIn, Lyft, MIT (also uses Django), Netflix, Pinterest (migrated from Django), Twilio, Uber (migrating from Flask to Go Python implementations), UK Gov

Initially created as an April Fools' joke, Flask is a minimal Python-based open-source web framework intended to supply the initial building blocks for a more capable web application. Additional functionality is intended to be cherry-picked from third-party extensions or custom-built as necessary.

Out of the box, Flask lacks an object relational mapper (ORM) capable of negotiating access to common database types, such as SQL. Instead, it makes use of third-party solutions, notably the open source ORM SQLAlchemy, which has been ported directly to Flask in the form of an-easy-to use extension.

Nonetheless, many commercial projects tend to fork Flask and implement their own declarative models, as the defaults often do not suit a project's workflow.

Since Flask also omits an integrated forms validation module, this functionality is usually provided by WTForms, again facilitated via a dedicated port that can create forms from SQLAlchemy models.

Flask is derived from the Werkzeug ('gear' in German) web server gateway interface (WSGI) library/utility, and the Jinja 2 template engine, both products of the Pocoo initiative, which have since migrated to the Pallets Python web development project.

The Jinja2 template engine is based upon the Django template language, making for a similar user experience across both frameworks in this respect. Both systems feature support for static file-handling. The functionality of Django's useful native collectstatic command, which can gather and copy over a group of static files, is mirrored in the third-party Flask extension Flask-Collect.

If you are pondering the value of Flask's high-effort implementation costs, it's worth considering the extent to which you can create and retain control over a project codebase by using a framework with so few dictates or default demands. Flask's extensibility has made it a popular starting point for deployments among some very big names (see 'Notable Customers' above) for whom this level of granular control was clearly worth the initial extra effort.

Proponents of rival Django contending that Flask is too lightweight for 'serious' work could note that Netflix migrated from Django to Flask APIs as a wrapper for their high-load orchestration tools. 

Django

CREATED:
2005
LICENSE:
BSD-3
URL:
https://www.djangoproject.com/
GITHUB:
https://github.com/django/Django
FORKS:
18,596
STARS:
43,221
USED BY:
282,618 projects
STACK OVERFLOW QUESTIONS:
204,483
NOTABLE CUSTOMERS:
Bitbucket, Disqus, Dropbox, Eventbrite, Indeed.com, Instagram, MIT (also uses Flask)

Named after influential jazz guitarist Django Reinhardt, Django began life as a side-project by two developers working for the Lawrence Journal-World newspaper.

Django was originally conceived as yet another custom CMS in a period where such home-spun frameworks were more common practice, although this one was leveraging the increasingly popular Python language. It was released under a BSD license in 2005, and three years later fell within the remit of the newly-created Django Software Foundation.

Unlike Flask, Django is predicated around the model–view–controller (MVC) paradigm, wherein the output of an application is sandboxed into a 'view', separate from the internal data structure and machinations of the controller framework. This enables easy GUI development and provides standardized pathways for backend control panels and other useful framework instrumentalities.

In contrast to Flask, Django comes replete with its own ORM, negotiating data models via Python classes. The framework also contains a relational database capable of processing HTTP requests via web templates, known as 'views'.

Out of the box, Django comes with a flexible admin control panel, an authentication system that accommodates extensions, RSS feed generation, support for geographic information system (GIS) applications, ability to generate Google sitemaps, and default security measures against SQL injection, cross-site scripting, and several other common attack surfaces.

In terms of core functionality, the most direct contrast between Flask and Django is that the latter can run multiple applications within one framework implementation—a granular approach that can only be replicated by Flask via the creation of individual views.

Looking for Python developers
who are fit for the job?

Speed

Flask's pared-down approach to framework provisioning generally yields faster and more responsive runtimes than rival Django—a benefit that users will have paid for in advance by the need for greater attention to architecture and feature development.

Unforked Flask is one place ahead of Django in terms of performance in 2019, according to TechEmpower. Based on the statistics from one GitHub framework benchmarking project, Flask is several places ahead of Django, with a 50th percentile latency response of 46.04 MS vs Django's 144.29 MS.

Unforked Flask is ahead of Django in terms of performance in 2019, but what about other parameters?
Tweet

Learning Curve

Anecdotally, some developers and teams have used Flask in a transitional capacity, to gain solid understanding of the core concepts which the two systems share before migrating over to Django and allowing the meatier framework to pick up the greater brunt of the workload.

Though there is the consensus that Flask has a more shallow learning curve than Django, Flask's stripped-down feature set should not generally be misinterpreted. Some notable names, including Pinterest (see above), have migrated from Django to Flask in order to dump framework overhead, or to take advantage of specific functionality that both frameworks offer (natively or via extensions), but which can be more easily or efficiently isolated and targeted in the sparser Flask.

Administrative Tools

Flask lacks an administration GUI by default. This is supplied instead by the flask-admin extension, which supports several ORMs, including MongoEngine, SQLAlchemy, and Pymongo.

Flask admin dashboard

However, the official help documentation does admit that applying HTTP Basic Auth to the admin backend is not an easy matter (see 'Security and Authentication' below). Configuring and customizing flask-admin can be time-consuming.

By contrast, Django comes complete with a full-featured and very popular administrative interface that can be customized with home-grown admin actions and granular user-permission levels—functionality that will be familiar to end-users from the likes of WordPress and similar popular PHP web frameworks.

Django admin GUI

Security and Authentication

As usual, Flask leaves us to add this core functionality if we need it. The FlaskSecurity extension offers a complete suite of security tools and protocols, including role management, password hashing, session-based authentication, basic HTTP authentication, and JSON or AJAX support. It also optionally provides capabilities for login tracking, user registration, and token-based password recovery and account authentication.

However, many of these features entail the installation of secondary and tertiary libraries such as ItsDangerous and Passlib. Depending on the number of extra packages required on a per-feature basis, this is likely to increase framework overhead and narrow the performance gap between Flask and Django—which may have been a critical consideration at the outset. Notwithstanding, the dependency packages are in themselves quite granular, allowing for cherry-picking and optimization.

Predictably, Django includes most of this functionality by default. Out of the box, a Django installation caters against cross-site scripting (XSS), clickjacking, SQL injection, and cross-site request forgery (CSRF). It also accounts for host header validation.

Django is packaged with a native user authentication system that offers a base suite of standard extensible tools, such as: 

  • Users and user groups
  • Forms and view tools restricting content on a per-user basis
  • Configurable password hashing
  • Granular permissions on a per-object or per-user basis

Third-party solutions are available for login-throttling, password strength checks, object-level permissions, and third-party authentication systems such as 0auth.

Departing from the Django Project Roadmap

If the developers of a Django implementation eventually feel the need to swap out some of its standard modules and functionality for more widely-used (or simply familiar) third-party resources, Django's essential value proposition is somewhat reduced.

Django allows for such configurations, but unlike Flask, it was not built with this approach in mind, and using it as a 'skeleton' framework defeats the purpose of the choice. Anecdotally, cases of this nature tend to occur when a project is unwilling to sacrifice the excellent admin facilities of Django but needs to depart from the Flask ORM.

Testing

Endpoint testing and handling is available in both Flask and Django via Python's integrated unittest framework, and each can be configured or swapped out for secondary solutions as necessary.

Despite this, Django's integrated automated testing framework is a strong argument in its favor, particularly if you need to run dummy database transactions where the test data should be purged afterward—a configuration which is not trivial to accomplish in Flask. 

As we might expect by now, Flask relies on third-party libraries for testing and accomplishes this by exposing the Werkzeug test client to input as well as negotiating local transactions for the test.

Mind Share

There are more than seven times the number of questions on Stack Overflow for Django vs Flask (29,378 against 204,483 at the time of writing).

Stack Overflow questions for Flask vs Django

However, Google Trends estimates a more consistent long-term rivalry in the same timeframe, although Django has a persistently higher rate of interest.

Conclusion

As we have mentioned, some consider Flask a transitional or educational framework that will inevitably lead to Django. However, others have concluded that the reverse applies—that Flask, in the hands of a developer now familiar with the bottlenecks and exigencies of a Python web framework, provides all the necessary building blocks for a mature implementation, and that Django is the one doing the preliminary 'hand-holding'.

In response to the oft-leveled criticism that Flask requires bespoke solutions to challenges that come pre-solved in Django, we should note that user-generated GitHub repositories address such shortfalls in the majority of cases.

Where rapid prototyping is a priority for development teams that have no specialization in either framework, Django will get the project to market sooner, with a performance penalty that in most cases is trivial, except at the highest volumes of data turnover.

In this regard, however, much depends on the data architecture adopted. Because Django assumes a number of set pathways and workflows for your project, it can sometimes prove to be brittle if you need to depart from its models and paradigms for any reason.

The binding relationship Django maintains between business logic, views, and database operations can make it inflexible or cause performance issues at scale, unless these factors are anticipated at design time.

For a brand-new build centered around Create, Read, Update, Delete (CRUD) functionality, unburdened by the complexities of migration from previous projects, Django is an attractive choice, so long as the strictures of its ORM implementation suit your needs.

If your project requires a higher level of interactivity with other systems, and particularly if it must negotiate with legacy data architectures, the extra upfront development time entailed in using Flask is likely to bring long-term reward.

*All stats in this article current as of August 2019

Is Flask just a runner-up to Django, or is the opposite true? Here is Iflexion's take on a Flask vs Django showdown
Tweet
Content type
Blog
Get your Python development
done by professionals

WANT TO START A PROJECT?

It’s simple!

Please wait...