When starting to develop a web application it is essential, in addition to analyzing the functional requirements, to choose the programming language and framework. As far as programming languages are concerned, the choice is vast and can be influenced by several factors. Certainly the skills of the developers can tip the scales towards one choice over another. Other factors may include the client’s particular requirements, the characteristics of the environment in which the application will operate, or the use of existing software.
If you are a Python developer, or a lover of this language, the choice will not be so difficult, barring the constraints mentioned above. At this point, the Hamletian doubt is: which Python web framework to choose? As usual in engineering, the answer is: it depends! Over the years, in fact, many web frameworks have been born. Some of them have become popular, others have remained niche, while still others have been abandoned after a while.
If we read JetBrains’ 2020 Python Developer Survey, Django and Flask are by far the two most popular Python web frameworks. Their success is partly due to the presence of mature communities and wide support and popularity. In addition, their goal is to provide the basic scaffolding of the application , leaving the development of the particular functionality of the software to the programmer. The difference between the two frameworks is how this goal is achieved.
In this article, we will look at the main features and differences of Django and Flask to identify the framework that best suits the needs of a web application.
Django and Flask are both free, open-source, Python-based web frameworks.
Django was born in the fall of 2003 from the idea of Adrian Holovaty and Simon Willison. The goal was, and still is, to simplify the process of website development. Therefore its philosophy is based on the Model-Template-View (MTV) model, a variant of the Model-View-Controller model. The development is therefore fast, with the possibility of reusing several components already present in the framework. The partitioning into 3 components (Model-Template-View) also allows you to divide the work between the various members of a development team as well as obtaining a clean and well-structured code. Django development is continuous and a new version is released approximately every 6 months. Despite this, compatibility with previous versions is maintained as much as possible.
Unlike Django, Flask is a microframework. Born as an April Fool’s joke by Armin Ronache, it has achieved unexpected success. It is mainly based on two solutions, Werkzeug (a server framework) and Jinja2 (a template library), already developed by Armin Ronacher. Its first version was a zipper file, called Denied Framework, that was automatically unzipped by the installer, which ran the two libraries at the same time. Flask’s architecture provides out-of-the-box URL routing, request and error handling, templating, cookies, unit test support, a debugger, and a development server. Compared to Django, however, it does not provide some typical web application features, including an ORM and authentication and permissions management. It is left to the programmer to choose how to customize the application using ad-hoc code or third-party libraries.
Main differences between Django and Flask
Let’s analyze the main differences between Django and Flask, to better understand which framework is more suitable for project development.
The first major difference between the two frameworks is the data model management. Django provides its own Django ORM (Object-Relational Mapping), while Flask does not. Data models, especially when working with relational databases, allow developers to connect database tables with programming language classes. This way, the programmer will use the functions associated with the classes to access the database without necessarily having to write the corresponding SQL commands. This greatly simplifies the code, although it can be limiting in some cases. But why doesn’t Flask provide an ORM since almost all applications interface to a database? It’s Flask’s philosophy. The developer is free to choose how to interact with the database without any imposition from the framework.
Another significant difference is Django’s use of the Model-Template-View model, an aspect that is not present in Flask. As mentioned earlier, the use of this model allows programmers to partition the development process by making the code structure cleaner and more well-defined, and improving development time. Flask, on the other hand, gives the developer the freedom to choose how to structure the code. This means that the development team must decide beforehand how to structure the project and define guidelines for good programming.
For these reasons, Flask is usually chosen for small and medium sized sites, such as forums and personal blogs, for prototypes or for single page applications (SPA). Django, on the other hand, is perfectly suited for large projects such as e-commerce sites, CMS and enterprise information systems.
Let’s go over the differences in more detail.
As mentioned earlier, Django includes a powerful ORM that supports a number of relational databases (SQLite, PostgreSQL, MySQL and Oracle). Django’s ORM provides support for generating and managing database migrations. Through the use of templates (Python classes) it is also easy to create forms and views, making this framework for all web applications that need to perform CRUD (Create, Read, Update, Delete) operations on the database. In cases where you need to write complex queries, however, the ORM is not suitable. The same goes for the use of NoSQL databases. In the latter case there are some projects including Django MongoDB Engine or Djongo.
Flask, on the other hand, gives you complete freedom on how to handle the data. Despite this there are several libraries available. For relational databases you can use for example Flask-SQLAlchemy, while for MongoDB Flask-PyMongo.
In conclusion, if your project is going to use a relational database, Django is the best choice because, thanks to the ORM, it makes everything much easier. If, however, you’re using a non-relational database, Django will make your life a bit more difficult. In fact, it’s possible that, unless you use Djongo, some features, including the admin panel, class representation of models and authentication, will not be exploitable.
On the other hand, with Flask you have the freedom to choose the ORM or ODM (Object Document Mapper) that best suits your needs. The price of this freedom is a steeper learning curve and greater risk of introducing errors.
Most web applications require users to authenticate and possibly manage permissions, i.e. what the user is allowed to do. Django provides both of these features along with account management and session support. Flask only provides support for cookie-based sessions. For account management, authentication and permissions management you can use Flask-Security.
A much appreciated feature of Django is the administration panel. It is nothing more than a web application already included in the core framework that allows you to quickly perform CRUD operations on your models. The whole thing is quite configurable with just a few lines of code. Again, Flask does not provide anything similar. One possibility is to use the Flask-Admin extension. This library supports a number of database backends, such as SQLAlchemy, Peewee, MongoEngine, and PyMongo, which can be extended with your own backends.
Routing and Views
Both frameworks allow you to map URLs to views, which are based on functions and classes.
In Django, URL and view definitions are done in separate urls.py and views.py files, respectively. When a request matches the definition of a URL, the request object, which contains the HTTP request information, is passed to the corresponding view. The view will implement the related business logic and take care of invoking the rendering of the correct template. Please refer to the official documentation for more details.
Compared to Django, the request object is global in Flask, so you can access it much more easily (as long as you import it). URLs are generally defined along with the view (via a decorator), but they can be separated in a centralized location similar to the Django model.
Django provides integrated forms management. This includes input handling, client and server side data validation. Various security issues are also addressed including cross-site request forgery (CSRF), cross-site scripting (XSS) and SQL injection.
As with other features, Flask does not support forms by default. However, you can use the Flask-WTF extension that integrates WTFormss into Flask.
Since both projects are based on Python, you can structure your applications in a way that reuses the implemented components.
Django uses the concept of apps. Using the django-admin command, you can have the framework create a basic app structure. The app will have a well-defined structure to house the view code. Just add the urls.py file and the templates folder to properly manage the views and the page rendering.
Flask uses the concept of blueprints instead. They are much simpler and easier to use. Obviously their simplicity implies more effort on the part of the programmer to manage and implement the functionality associated with them.
Templates and static files
Templates are html files inside of which you can inject some dynamic information generated by the backend. Flask uses Jinja2 by default, while Django has its own engine to render templates. The syntax and feature set between the two modes are very similar.
Both frameworks also have support for handling static files. Django also provides a command to collect all the static files used by the various components and save them to a predefined location, which is useful for putting the application into production.
Flask does not support asynchronous requests, while this feature was introduced in Django 3.1. Thus, a view can be made asynchronous using the async keyword. You cannot use the async functionality when interacting with the ORM or operating at the cache level. To use a synchronous call within an async function, simply use the sync_to_async decorator.
Another possibility to execute asynchronous tasks is Celery. This library allows you to create even a very complex asynchronous task execution service. Integration with Django is highly supported and documented.
Django has built-in protection against a number of possible attacks including:
- Cross-site scripting (XSS). XSS attacks allow an attacker to inject client-side scripts into browsers. Django templates protect your application from most XSS attacks.
- Cross-site request forgery (CSRF). CSRF attacks allow a malicious user to perform actions using another user’s credentials. Django has built-in protection against most CSRF attacks. For example all submissions of data from forms must include the csrf token to be accepted.
- SQL injection. It is an attack in which a malicious user is able to execute SQL statements on a database. Django query sets are protected from SQL injection because the queries are constructed using parameterization.
Continuous updates to the framework are geared towards not only providing new functionality, but also correcting any vulnerabilities that are found.
Flask, on the other hand, is a much smaller framework and consequently has fewer vulnerabilities. It’s the developer’s job to handle any vulnerabilities that may arise when programming functionality or integrating other libraries. This means that Flask is just harder to keep secure than a project developed in Django. The level of security, however, is very similar.
As mentioned earlier both frameworks are very popular in the Python developer community. In fact, Django is designed for fast development of complex, scalable and maintainable web applications. In contrast, the simplicity of Flask allows the creation of small or medium applications very quickly. Precisely because of this aspect it is often used to create microservices.
The most popular projects developed in Django are the following:
Websites that use Flask instead are:
Which framework to choose?
In consideration of what has been presented, the question arises. As usual there is no absolute answer because everything depends on your project.
If you are a beginner in the development of a web application the advice is to use Flask. Being very simple and flexible it will allow you to better understand the management of requests, views and template rendering. You won’t have any additional functionality except those introduced by the use of third-party libraries.
However, if your project is more complex, the advice is to use Django. While Django does not have basic support for NoSQL databases, it is an excellent ally for developing applications that work with databases. Some features, such as the administrator panel, form definition integrated with templates, and authentication and authorization management will allow you to focus your development on the features that characterize the application. Moreover, you will reduce the development time and you will have a highly reliable product over time.