TubeSum ← Transcribe a video

I built the same app 3 times | Which Python Framework is best? Django vs Flask vs FastAPI

Transcribed Jun 28, 2026 Watch on YouTube ↗
881.9K
Views
19.5K
Likes
509
Comments
376
Dislikes
2.3%
📈 Moderate

AI Summary

✂️ Creator Tools: Viral Hooks

AI-generated clip ideas for Shorts based on the transcript

Python Framework Battle: Stats Show Clear Winner?

45s

Direct comparison with Google Trends, GitHub stars, and speed benchmarks sparks debate among developers.

▶ Play Clip

Flask: 49 Lines of Code for a Full App

41s

Shows how minimal Python code can create a working app, appealing to beginners and highlighting Flask's simplicity.

▶ Play Clip

FastAPI's Hidden Gem: Auto-Generated API Docs

54s

Demonstrates a powerful built-in feature that saves time and impresses developers with automatic validation and documentation.

▶ Play Clip

Django Admin Panel: The Feature Flask and FastAPI Lack

60s

Showcases Django's built-in admin interface as a major selling point, highlighting a key differentiator for full-stack projects.

▶ Play Clip

[00:00] which python web framework is the best

[00:02] flask is considered the most popular

[00:03] beginner framework django is the most

[00:05] popular full stack framework offering

[00:07] the most functionality and is used by

[00:09] many companies in production and fast

[00:12] api has only been around for three years

[00:14] but it took the hearts of the python

[00:15] developer community by storm

[00:17] facilitating rapid development and

[00:19] offering a tremendous web app speed when

[00:21] comparing google trends flask is on top

[00:24] closely followed by django but fast api

[00:26] is rising quickly based on github stars

[00:28] django is the winner but also closely

[00:30] followed by flask and fast api catching

[00:33] up quickly and in the speed benchmark

[00:35] test fast api is the clear winner

[00:37] outperforming the other frameworks by a

[00:39] factor of two or even three so which one

[00:41] should you use it's hard to give one

[00:43] clear recommendation because as always

[00:45] the answer depends each framework has

[00:47] its own strengths and weaknesses and all

[00:50] of them are great so in this video i

[00:52] created the same to-do app with all

[00:53] three frameworks in the process you

[00:56] learn how to use each framework and

[00:57] hopefully get a better feel for the

[00:59] trade-offs between each of these so in

[01:01] the end you can make the best choice for

[01:03] your next project the project we are

[01:05] going to build is a simple to do app

[01:07] providing functionality to add update

[01:10] and delete to-do's for each app you'll

[01:12] learn how to use a database use html

[01:14] templates and implement the api routes

[01:17] so let's get started let's start with

[01:19] flask flask is well established in the

[01:21] python community it is loved by

[01:22] beginners and experts for its simple

[01:25] syntax while still being capable of

[01:27] managing full-blown production-ready web

[01:29] apps so let's see how to do it first i

[01:31] recommend to create a virtual

[01:32] environment and then activate it then we

[01:34] need to install flask and also flask sql

[01:37] alchemy to work with a database then we

[01:39] create one file app.pi and import all

[01:42] classes and functions from flask that we

[01:44] need the convention is always to create

[01:46] an app instance with a double underscore

[01:48] name and then creating a route is as

[01:51] simple as defining a function and using

[01:53] the appropriate decorator here we say

[01:56] app.get and then a simple forward slash

[01:58] since this is our home page this would

[02:00] now display hello world on the website

[02:03] in order to use the database we import

[02:05] sql alchemy now we have to set some

[02:08] configuration variables for example the

[02:11] name or path to the database here we

[02:13] simply use a sqlite file and then we

[02:16] create a database instance by using sql

[02:19] alchemy and passing the app to it now we

[02:21] create a model for the database so we

[02:23] create a class to do that inherits from

[02:26] db.model and we give it three columns

[02:28] with the appropriate data type we want

[02:31] an id a title and a complete flag for

[02:34] the to-do item and then we call

[02:36] db.createall to create and initialize

[02:38] our database

[02:40] now of course we want to use this so in

[02:42] the home route we call

[02:44] db.session.query2do to retrieve all

[02:46] to-do items and then we use the render

[02:49] template function from flask with a

[02:51] template file name and the to-do list is

[02:53] additional arguments so that we can use

[02:55] it in the html code of course we need to

[02:58] create the template so we have to create

[03:00] a folder named templates and then a file

[03:02] that we call base.html

[03:04] and here we can use normal html code

[03:07] that displays a form and all to do items

[03:10] now what is special here are these curly

[03:12] braces with percent characters this is

[03:15] special ginger 2 template syntax that

[03:17] basically allows us some python-like

[03:19] logic for example we can have a for loop

[03:22] where we iterate over all to-do's and

[03:24] show the id and title for each to-do

[03:26] then we have an if-else statement to

[03:28] check the complete flag and show the

[03:30] label in a different style and then we

[03:32] also need closing statements for the if

[03:34] and also for the for loop we also create

[03:36] two links that are the buttons to update

[03:39] and delete a to do and the important

[03:41] part is that the ahref points to the

[03:43] update and delete route for this

[03:45] particular to-do id please note that

[03:48] these will be get requests which is not

[03:50] a best practice for updating and

[03:51] deleting data but it works and for

[03:53] simplicity i will use it like this now

[03:55] we go back to the app.pi and can

[03:57] implement the remaining routes first

[04:00] let's create a route to add a new item

[04:02] this has the

[04:03] app.postdecorator since it should be a

[04:06] post request we get the title

[04:08] wirerequest.form and then we create a

[04:10] new to-do item and call

[04:13] and db.session.add.com the changes as

[04:15] last step in here i use the redirect

[04:17] function together with the url4 function

[04:19] to redirect and load the updated home

[04:21] page the update route works similar here

[04:24] we query the particular to-do item with

[04:26] the id remember that we also specified

[04:29] the id in the html code then we update

[04:32] the complete flag commit the changes and

[04:34] again redirect to the home page and the

[04:36] delete route is the very same code

[04:38] except that here we delete the to-do and

[04:40] that's it 49 lines of code is all we

[04:42] need super simple and straightforward

[04:44] this is where flask really shines it

[04:46] won't be that quick with the other two

[04:48] frameworks now to run the app we can

[04:50] export the environment variables flask

[04:52] app equals app.pi and flask n equals

[04:56] development to get hot reloading and

[04:58] then we say flask run to start their

[05:00] development server and now we can add

[05:02] new to-do's update them and also delete

[05:04] them

[05:05] next let's use fast api it's one of the

[05:08] fastest python web frameworks out there

[05:10] right now it also provides an easy

[05:12] syntax allows for rapid development and

[05:14] offers some more nice to have features

[05:16] like automatic interactive documentation

[05:18] and type validation that's why

[05:20] developers love it and it's rising so

[05:22] fast in popularity that i think it will

[05:24] soon catch up with flask and django

[05:26] let's create a new virtual environment

[05:27] for this project then we need to install

[05:30] fast api we also need an asgi server for

[05:33] example uv corn and for the template

[05:36] files and database support we need

[05:38] python multipart sql alchemy and ginger

[05:41] 2. these are essentially the same

[05:43] dependencies as we get with the flask

[05:45] and flask sql installation here we

[05:47] create three files app.pi models.pi and

[05:50] database.pi we need a little bit more

[05:52] code for each compared to flask and we

[05:54] want to maintain a clean project

[05:56] structure the basic app will be very

[05:58] similar to before we import fast api

[06:01] create an app instance and create a

[06:03] function that we decorate with app.get

[06:05] here we return a dictionary which will

[06:08] be automatically converted to a json

[06:10] response one cool thing to mention here

[06:12] is that we could also declare the

[06:14] function as async dev since fast api

[06:16] supports asynchronous programming out of

[06:19] the box and allows for an extremely fast

[06:21] web app but for simplicity i'll stick

[06:23] with a normal function here fast api

[06:26] heavily relies on tie pins so if we want

[06:28] a dynamic route we use this syntax we

[06:31] put the argument in curly braces in the

[06:33] route and then we use the same name as

[06:36] function argument together with a type

[06:38] hint in this case it should be an

[06:39] integer this is concise reduces bugs and

[06:42] gives us automatic type checking which

[06:44] we will see later so let's continue with

[06:47] our to-do app we need a few more imports

[06:49] from fast api we also import a few

[06:52] requirements from starlet this is the

[06:54] asgi framework that fast api is built on

[06:57] top of then we specify our template

[07:00] directory and use a template response in

[07:02] the home function we pass the request as

[07:04] argument and also the database which is

[07:07] a session object that depends on another

[07:09] function don't worry about this syntax

[07:11] yet it will become clear in a moment but

[07:13] note that again for each argument we are

[07:15] using typins here and then again we

[07:17] query the database for all to do's and

[07:20] return a template response that needs

[07:22] the html file the request and the to-do

[07:24] list in this case the arguments for the

[07:27] template file are passed as dictionary

[07:29] now we also create a template directory

[07:31] and the base.html file and here we can

[07:34] use the exact same code as before since

[07:36] we are also using ginger 2 templating

[07:39] syntax now let's set up the database we

[07:41] get the imports and set up the path to

[07:43] the sqlite database then we need to

[07:45] create an engine we also need to create

[07:48] a session instance and lastly we declare

[07:50] the base class from which the model will

[07:52] inherit in the next step for the model

[07:54] we import the database and this base

[07:56] class we just declared and then we

[07:58] create a to-do class that looks very

[08:00] similar to the one from the flask app

[08:02] but now we inherit from base then we

[08:04] define a table name and use the same

[08:07] fields as before now we can go back to

[08:09] app.pi and make use of all of this we

[08:12] import the session class so we can use

[08:14] it as type hint we import the models the

[08:16] session local object and the engine then

[08:19] we create all database tables and then

[08:21] we create a helper function to access

[08:23] the data by session this will now be

[08:25] passed to the home function as a

[08:27] dependency which means if the database

[08:30] cannot be accessed then also the request

[08:32] to this route throws an error and this

[08:34] is already handled for us by fast api so

[08:37] you can see we need a little bit more

[08:39] code here but in return we get a lot

[08:41] more functionality already and a safer

[08:44] code now inside the function we can use

[08:47] the session object and query the

[08:48] database with the same syntax as in the

[08:50] flask app let's continue and add the add

[08:53] route which must be a post request

[08:56] as parameter we also use the request and

[08:58] the database and now as new argument we

[09:01] also put in the title which is a string

[09:04] that comes from the form and then again

[09:06] we create a new to-do added to the

[09:08] database and commit the change and then

[09:10] i get the url of the home page and

[09:12] return a redirect response i also

[09:14] specify a particular status code which

[09:17] is needed because we now change from a

[09:19] post route to a get route very similar

[09:21] we now add the update route and as

[09:23] mentioned before we use the to do id as

[09:26] dynamic argument with a tie hint then we

[09:28] query the to do change the complete flag

[09:31] commit the change and again redirect to

[09:33] the home page and finally we use the

[09:35] same code for the delete route but here

[09:37] we delete the to-do item and that's it

[09:39] we can now start a server by saying

[09:41] uvicorn app colon app the first is the

[09:44] file name and the second is the app

[09:46] instance we also use minus minus reload

[09:49] while we are in development mode and

[09:50] then we can go to this address and have

[09:52] a working to-do app one more cool

[09:54] feature we also get out of the box with

[09:57] fast api is automatic api documentation

[10:00] so we can go to the slash docs route and

[10:03] here we see all the different api

[10:05] endpoints together with the type for

[10:07] example we can click on the add post

[10:10] endpoint and then we see more details

[10:12] like that it needs a title as string we

[10:14] can also try this out enter a title and

[10:17] execute the command and then we can

[10:19] inspect the result so here we see we get

[10:21] the response code 200 so all is good and

[10:24] we see the raw template response that is

[10:26] visible on the page we could also try

[10:29] another route so let's test the update

[10:31] route this needs a to-do id as integer

[10:34] so if we try to send a string here then

[10:36] it wouldn't let us and on the page we

[10:38] would see an error code and again all of

[10:41] this is handled for us by fast api and

[10:44] this is possible because we used the tie

[10:46] pins all right and that's the to-do app

[10:48] with fast api i hope i could demonstrate

[10:50] some of the cool features here now for

[10:52] the final app we use django while flask

[10:54] and fast api are considered to be more

[10:57] like a micro framework change is a full

[10:59] stack framework with many batteries

[11:01] included it's the backend framework of

[11:03] choice for many fortune 500 companies

[11:05] while the learning curve might be

[11:06] steeper than with the others it offers

[11:09] so many features that it makes your life

[11:11] easier once you know your way around it

[11:13] again i start by creating and activating

[11:15] a virtual environment then we only need

[11:17] to say pip install django this comes

[11:19] with all the requirements that we need

[11:21] now we say changu admin start project

[11:24] and give it the name to do app this

[11:26] creates a new folder and inside the

[11:28] folder we have the manage.py file and

[11:31] another subfolder with the same name and

[11:33] all the starter files we need we cd into

[11:36] the first folder and can run python

[11:38] manage.pi run server this starts the

[11:41] server and we have the initial app up

[11:43] and running for now we quit the server

[11:45] again and say python manage.pi start app

[11:48] and the name to do list an app is a

[11:51] component inside a project that is

[11:53] responsible for certain things like here

[11:55] for managing the to-dos in this simple

[11:58] project this is the only app we need but

[12:00] imagine if we add authentication then we

[12:03] could put this in another app to keep

[12:05] the logic separate and clean after

[12:07] creating an app we also need to add the

[12:09] app name to the installed apps in the

[12:11] settings.py file now we want to add the

[12:14] views so inside to do list.views pi we

[12:18] add a function that gets a request and

[12:20] then we return the render function with

[12:22] a template name and this dictionary all

[12:24] items we want to pass the missing to-do

[12:27] part will be implemented in a moment for

[12:29] each view we need to register a url so

[12:32] we create a urls.pi file inside the

[12:35] to-do-list folder import the path

[12:37] function the views module and then we

[12:39] define all url patterns we want to add

[12:42] in this case we leave the route of the

[12:44] path empty since this is our home page

[12:47] and then we use the corresponding

[12:48] function and can also give it a name now

[12:50] we go to the to do app.urls.pi

[12:54] and use the include function to include

[12:56] all urls from the to do list app you can

[12:59] see that there already exists an admin

[13:01] path this is because django gives us an

[13:03] admin panel out of the box which we will

[13:05] see in a moment now we will need to

[13:07] create the template file so let's create

[13:09] a new templates folder in the top

[13:11] directory and then we again create the

[13:13] base html file and put in the same code

[13:16] django uses its own templating language

[13:19] which is similar but slightly different

[13:21] than the ginger 2 template but in this

[13:23] case we only have a for loop and an if

[13:26] statement and this is actually the very

[13:28] same syntax but there is one thing we

[13:30] need to change in the form part we need

[13:32] to add the csrf token this is a security

[13:36] mechanism that prevents attacks to the

[13:38] form but we don't need to do more than

[13:40] adding this here now we need to go back

[13:42] to the settings.py and add the templates

[13:45] folder to the directories key now we

[13:47] implement the model class so inside the

[13:49] to-do list models.py we create a class

[13:52] that inherits from models.model and then

[13:55] we again create the same fields with the

[13:57] correct data type and we also implement

[13:59] the string method to see an accurate

[14:01] description here we don't need to create

[14:03] an id since django does this for us now

[14:06] in the console we say python manage.pi

[14:09] make migrations followed by

[14:11] pythonmanage.pi migrate then we also

[14:14] create a super user because i want to

[14:16] show you the admin panel so we say

[14:18] python manage pi create super user we

[14:21] follow the instructions and put in a

[14:23] name and email and the password as next

[14:25] step we go to the admin.py and register

[14:28] the to-do model and now we go back to

[14:31] the views.pi import the to-do class and

[14:34] then query all to-do's in the index

[14:36] function let's run the server again and

[14:38] test this we see the home page with zero

[14:41] to-do's for now if we click on the add

[14:43] button we get an error since we haven't

[14:45] implemented this view yet but one cool

[14:47] feature that is already available is the

[14:49] admin panel so if we go to the slash

[14:52] admin route we can log in with the super

[14:54] user we created and here we can see

[14:57] different groups and users if we would

[14:59] add authentication we also see the to-do

[15:01] models with all the fields we specified

[15:04] and here we can interact with our

[15:06] database so we could add or modify the

[15:08] database entries right from the admin

[15:10] panel this is one very cool built-in

[15:13] feature that you don't get with the

[15:14] other frameworks so now let's log out

[15:17] again and implement the missing views so

[15:19] we import two more functions and then

[15:22] implement the add route we require that

[15:24] this should be a post method by using

[15:26] this decorator we could also check the

[15:29] type of the request inside the function

[15:31] but i wanted to show you this second way

[15:33] of doing it inside the function we then

[15:35] create and save a new to-do and redirect

[15:38] to the index page now we implement the

[15:40] update function this gets an additional

[15:43] parameter to do id which is then be used

[15:46] to query for this to do and then we

[15:48] change the complete flag and save it and

[15:50] again redirect the syntax for working

[15:52] with django models is slightly different

[15:55] than before but in my opinion it's even

[15:57] more simple and straightforward and the

[15:59] last view we need is the delete view

[16:01] which is very similar but here we delete

[16:03] the to do and now we only need to add

[16:05] all these views to the urls.py

[16:08] so in here we add all the paths with the

[16:10] corresponding route and view function we

[16:13] can use this syntax with a data type and

[16:16] parameter name to add dynamic views and

[16:18] that's it we can now go back to our app

[16:21] and we should be able to add new to-do's

[16:23] and then update and delete them awesome

[16:26] alright that's it you can find the code

[16:28] for all apps on github the link is in

[16:29] the description this video was a lot of

[16:31] work so if you enjoyed it please hit the

[16:33] like button i'm also interested to hear

[16:35] what's your favorite framework so please

[16:37] leave me a comment below and as always i

[16:39] hope to see you in the next video bye

⚡ Saved you time reading this? Transcribe any YouTube video for free — no signup needed.