Flask vs Django - Why NOT Choosing Flask Is Your Best Bet In 2020?
October 6, 2020
I am a former Python developer with 10 years of experience in coding, 8 years in Python, and 6 years in leading Python teams. Contributing to or taking over more than 10 large (3-6 backend devs) web projects. Now a CEO of a Python software development company.
Flask and Django are Python web frameworks. Despite being completely different, they serve the same goal - building web applications or web services, where the interface to the backend is mostly HTTP based, which is either REST, GraphQL, grpc, or websockets.
And what is Django? Django is a large SQL-based framework while Flask is a much smaller one. They both have great communities and excellent documentation. As of 2020, they both are mature, stable, and together take approximately 80% of Python web applications market share.
If you imagine that your project is like a trip to an unknown place, then you have to reach a certain destination within a specified deadline. You only have a compass, you don’t know the topology and it could be 1km, 100km or 1000km.
To complete your task you may choose whatever you want, from the rocket to take a walk.
Django is like a heavy SUV, not the best for 1km (taking a walk could be better) but does the job and not the best for 1000km but still, a reasonable choice (airplane or a helicopter could be a way to go). You definitely cannot go around the earth with it but at least you can start driving to the nearest shore, then you can think about the next steps, like buying a plane or maybe a boat?
It is excellent for most of the trips, though quite heavy for highways and a way more complicated than a kick scooter or bicycle for example.
What is Python Flask then? It is like hitchhiking a trip. It is adventurous, it is fun, you can learn a lot and it definitely gives you lots of freedom. But it certainly is unpredictable. At the beginning of the trip, you think that it will be the best time in your life but as you go along it will be getting worse and worse. You will wait hours for a car that will take you in the correct direction or you will be running away from dangerous animals. The longer the trip the worse it will be.
Ok, enough metaphors comparing Flask vs Django - give me some beef.
Flask is a good framework when you want to learn how things work. You have to use many external libraries and do a lot of coding on your own. If you are thinking about using SQL, plan to have some background tasks to run, or have more developers coming to the project, Flask would certainly be a bad idea in the long term (more about this later).
There are some reasonable use cases I can think of where Flask would be a reasonable choice:
- some small microservices when you need to design API for ML model,
- API abstraction for controlling devices with a different protocol like a security camera,
- API for a no-SQL database like DynamoDB or full-text search like ElasticSearch.
- Preparing an adapter microservice that translates SOAP API into easier JSON API could be another valid use case.
Django is the best for building a majestic monolith, with it you can easily build a massive application that 4-8 developers can work on simultaneously. At some point, after having the initial shape of your system (and having more and more engineers), you can easily start breaking it down to smaller microservices by chunking off already defined parts of the application. This is a perfect way to plan the future growth of the whole system - start with a monolith and then break it down after having a better understanding of how the features are sorted out. Never the other way around.
For some of the microservices you can still use it or you can use more flexible frameworks like Pyramid or FastAPI.
The key element of choosing a technology is not about knowing its strengths but being aware of the trade-offs.
When thinking about Django, you should think about it as a SQL Web Framework. It is the best at translating the real world into SQL data (and opposite).
Choosing Django forces you to stick to the SQL database.
Django ORM is a higher abstract ORM. You are sacrificing the flexibility of writing custom sophisticated aggregate queries for a perfect tool that maps models onto tables.
In 99% of use cases, this is what you want. The rest is more data analytics queries for reports including self-joins or CTE queries. I can count cases on one hand when we had to write a raw query for some complex tasks - and even then in most cases, you can get away with mixing in some raw SQL to ORM-generated one. So the need to write fully-fledged raw SQL is very rare.
Also, even if you use a lower level ORM like SQLAlchemy, these kinds of queries are most likely to be super slow. So you will still have to denormalize the database to aggregate your information to a separate table.
If you are a data analyst or have a deep SQL background using Django ORM will require you to change your mindset on how to write queries. It can be difficult, I know many people that were not able to do so and they hated Django ORM. This caused them to choose a different framework + SQLAlchemy and thus substantially slowing down their product development.
Async programming in Django is still hard, despite Django adding support for async in 3.1.
Flask framework trade-offs
There are definitely many more trade-offs with this web framework. What’s even worse, they are not formulated properly in the Flask community and consequently many people choose it and struggle with its architecture later on in project development.
Moreover, I was unable to find any critical blog post or Reddit thread about it, which should be a red flag right away for anybody searching for a framework - nothing’s perfect.
Flask features are really primitive and they quickly become broken when having to handle a slightly harder use case. For example, take middleware implementation as a callback before and after request - try to specify certain order of execution for them (more on this below) or to control context before and after the request. It’s impossible or requires hacking with global objects.
Also, they execute in reverse order of declaration. So imagine you do a refactor, moving middleware callbacks to different places and you change the order and bang, you’ve just blown up the production.
This should be a deal-breaker for most of the use cases because the order of middleware execution will be required sooner or later.
Another example is obviously global objects (app, g, or request). I could write a separate blog post about my struggles with straightening up many Flask projects. I can definitely say that I’ve learned everything there is about this framework, be it thread-local variables or local stacks. But god, my brain still hurts when I think about them.
Having global objects is so dangerous that it should never be allowed in any case. It is like giving a 2-year-old a lightsaber to cut a carrot. You would think that a team of senior developers would not kill themselves. But no, trust me, they will. I saw that happen way too many times.
I could write a separate blog post about why Flask has broken architecture...oh wait - I already did.
Django is a mainstream framework, the standard. Lots of people have a problem with that and they are trying to use something different just because Django is so popular.
And I am not without guilt myself, back in 2012 I was choosing all the other frameworks except Django because I thought it would limit me. Accidentally I jumped into an existing project in Django and it opened my eyes. Everything was there, everything was organized as it should be. I was way more productive and could focus on real problems of the client instead of fighting with the framework or writing boilerplate code.
So, my advice to you is to not be like me, especially in 2020, when Django is much better today.
If you are a Python developer and thinking about doing web development, not knowing or ignoring Django is like shooting yourself in a foot. Most of the web development can be done way faster using Django.
Are you wondering which framework is more flexible Flask or Django? Many developers have only one answer here: Flask is more flexible than Django. End of story. But are you really sure?
In 2012 there was a really big difference, back then in Flask you could choose different libraries for a session, forms, templates, custom user model, etc.
But in 2020, it is all gone, most of these things are moved to the frontend. Also, Django is way more flexible now, you can customize the user model, we are no longer forced to use the backend to generate the frontend.
So, what is left to be flexible about? Probably just a database connector. In Django choosing noSQL database makes 80% of the framework useless. But still, you have 20% really good stuff that you can use exactly the same as using Flask.
The only good argument here is that, should you use a large Django codebase just to use 20% of it? I think yes and this is because 90% of other projects you will do in Django, so you will not need to learn another framework. If you still would like to broaden your horizons, you should take a look at Pyramid which is an excellent framework that will help you have a different look at how a web framework could look like.
This one is easy to compare in case of Flask and Django. It is like having a bicycle vs bicycle with permanent training wheels. You don’t yet know how to ride it. Which one would you choose to ride faster? 4 wheeled seems like a better choice probably but it works only for the first 1-2 days and then a normal bike beats easily.
I can demonstrate the productivity of a team without a priori experience in Django/Flask using both frameworks in the following chart:
After some time and size of the project, the productivity of the Django team will exceed that of Flask’s team. The Flask team’s productivity will even decline. Why? Because there will be bugs with inappropriate usage of many features like global objects, poor quality serialisation libraries, unreliable and slow tests.
This is my experience, I overtook more than 10 larger (2-6 people team) projects in Flask, all of them had exactly the same problems.
Performance of what? If you are building a fully-fledged web application, then the performance difference between all Python frameworks is negligible. In the worst-case scenario, you will have to double the number of pods in your Kubernetes cluster.
There are two cases where performance matters:
- First is the database type. SQL is the bottleneck in some specific use cases. If you have enough experience to know the trade-offs of certain noSQL database that you have in your mind and you know from the start that SQL won’t be a good choice - then you should go with that noSQL database and then a large portion of Django will be just useless to you (and Flask will be still Flask).
- Second is when your application is going to be async heavy (like a chat app, bot app, etc). Then obviously neither Django nor Flask is a good option.
Django is obviously the winner here and I’d say by a large margin too. Django, as a large framework, controls most of the aspects of the web application and this allows it to enforce security standards, even if devs are not aware of them.
The other thing is that Django addons are way more powerful than Flask addons and thus can also strictly control the security aspect. Take for example the authentication layer - for example, there’s a well-known Simple JWT addon: it takes 5 minutes to install and configure and you have an industry-standard authentication layer.
Flask on the other hand is not able to give you any security guarantees. You are there on your own. You need to learn lots of things on your own. Are you going to screw things up in the process? For sure. You can think that you are smart enough, probably you are but then you have a CEO with requirements and deadlines and your team that you hired in a hurry. Are you sure they won’t mess things up? Will you have time to look at their hands all the time?
I have seen super-smart CTOs with PhDs and lots of years of experience designing SQL-based JWT authentication from scratch that had performance problems. It happens. Don’t overestimate your skills.
There is a huge difference between these two frameworks. Django should be a default choice for 95% of projects. Flask should be used with caution for small projects if someone likes to learn a lot.
In Ulam we use the following conditions to choose the framework for the next project:
- Web API + SQL - Django, unless you are doing async or really complex SQL operations.
- 1 month 1 person project where you don’t use SQL - use Flask but make sure the project doesn’t have any perspectives to grow substantially
- noSQL database - Pyramid
- large async work - FastAPI
Are you looking for an experienced partner building web applications? We will help you choose between Django and Flask or other frameworks if needed. Drop us a line and we will be more than happy to advise you with the best solution for your project.