Building Data-Driven Web Apps with Flask and SQLAlchemy Transcripts
Chapter: Routing and URLs
Lecture: Refactoring view methods with Flask blueprints
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
So here we are in our Flask app.
0:02
And it's pretty standard, right?
0:04
This is like how they tell you how to do it in Flask.
0:06
Import flask, you create your app
0:09
and then you create your view methods.
0:10
You put your app.route on them.
0:12
Well, okay, that's how you get started maybe sometimes.
0:16
But this is a terrible way
0:17
to organize real applications.
0:20
It definitely encourages just cramming
0:22
your entire web app into like a single file.
0:26
Bad idea. And it's bad because Flask has a really
0:29
super cool way of organizing your views
0:32
that you don't have to do much at all about.
0:34
You just change basically a one word right there
0:37
and you're good to go.
0:38
So what we're going to do in this little short segment
0:41
is we're going to reorganize our code
0:43
not because it's really that long
0:45
you can see it's actually short
0:46
but so that it's ready to grow
0:48
as we build up this real application.
0:51
So let's do a couple of things.
0:53
The first thing I want to do
0:54
is actually deal with this fake data.
0:56
We're going to have a real database
0:57
with lots of interesting stuff going on.
0:59
So I want to create a special part
1:01
of my application just for that.
1:04
I'm going to call that services.
1:07
Not web services, but services that are provided
1:09
through our application like stuff that deals with packages
1:12
stuff that deals with users, and so on
1:14
so we can isolate that over here.
1:16
So I'm going to create something called
1:19
package_service. Like so.
1:23
And then let's just take this code and put it over here.
1:27
All right. Not super interesting.
1:29
Remember, we don't have our data yet.
1:31
We don't have our database.
1:32
That's coming later.
1:34
But, we can get started this way.
1:36
So we're going to come here and say import
1:38
pypi.org.services.package_service
1:42
and let's say as just package_service.
1:44
I noticed there were some errors down here
1:46
so we can come and say .get_latest_packages.
1:48
Just like that, I think that's the only place it's used.
1:51
Okay, let's just make sure real quick
1:53
that we didn't break it. We did not, okay super.
1:59
That's what I expected.
2:00
So, that organizes it a little bit
2:02
gets some of the data access out of here.
2:04
But this, this is the ultimate problem right there.
2:08
However, it's tricky to reorganize it as is.
2:11
So this needs to be created
2:13
and then it needs to be used
2:15
to start the app in this main app.py.
2:18
And yet, it has to be available at the time
2:20
that these are parsed so that we can apply the route.
2:24
So, that can make it really tricky.
2:25
There are patterns that allow you
2:26
to share this across the file, different files
2:29
but because Flask has this built in thing
2:31
called Blueprints which are ways to predefine
2:35
these routes and then later apply them
2:37
after the app is created, we're going to use that.
2:40
It's really nice.
2:41
So, let's go down here and create a folder called views.
2:45
And in the views folder, we're going to create
2:47
let's start with two things
2:49
we'll have a file called home_views
2:53
keep adding that to get up.
2:54
And we'll create another one
2:57
called package_views.
2:59
We don't really directly work with these often
3:02
so the name isn't super important.
3:04
Okay, so what we need to do is we want to take
3:07
this is going to be the home stuff
3:09
and we're going to put it over here.
3:12
Well, immediately you can see the problem.
3:14
Some of it's just an import problem, that's easy.
3:17
Let's go up here and grab that
3:22
'cause of my renaming.
3:23
Okay that was easy, but the one that's left here
3:26
hmm not so much.
3:27
So, we're going to use this thing called
3:28
a Flask Blueprint.
3:30
And the way it works is we're going to come over here
3:31
and we're going to say Blueprint
3:34
you can also call it app if you want
3:35
but let's not confuse things here.
3:37
So we say Flask, which we have to import at the top
3:40
we say Blueprint and in here
3:42
we're going to give it three pieces of information.
3:45
A friendly name, so in this case
3:46
I'm going to call it home, 'cause it has to do
3:48
with the home_views.
3:50
And then for the import name
3:52
I'm going to give it the __name__
3:53
which is the name of this file, home_views.
3:57
And then we want to set the template folder to templates.
4:02
And then all we have to do is go down here
4:04
instead of doing @app.route
4:06
we say @blueprint.route.
4:10
So, we just replace app with blueprint
4:14
like so. Now, this sort of works
4:17
this will sort of add some features here.
4:21
And we go and run it
4:22
let's see what's going to happen.
4:23
We don't need this anymore.
4:25
So, let's see if we run it
4:26
is it going to be amazing?
4:28
The chances are it's not going to be amazing.
4:31
That didn't work.
4:32
But remember, potentially these
4:35
these are created before the app is there.
4:38
And how does the app instance know about it?
4:40
Well, we can do, there's a couple of things we can do.
4:43
But, let's define, let's do a little bit of work here.
4:46
Let's define a main
4:50
and move that up.
4:51
Now, before we do this let's call another function
4:53
called register_blueprints
4:55
or whatever we want to call it.
5:00
Like so and then all we got to do is say
5:04
so import home_views
5:07
and then we can go over to the app
5:09
this is the one that now exists here
5:11
and we can say register_blueprint, like so
5:15
and pass it in home_views.
5:17
And that's it, that basically goes back
5:19
and tells the app about the few routes
5:21
and methods and what not are defined over here.
5:25
It should work, let's give it a try.
5:27
And it did not like that. Oh
5:32
we can't aim for home_views, we have to
5:35
aim for, register home_views not blueprint.
5:38
Let's try that again. All right, there we go.
5:41
So, looks like it's running
5:44
but does it work? Moment of truth.
5:47
Of course it works. Of course it works.
5:49
Isn't that nice?
5:50
So that lets us break our code apart.
5:52
Our view code into these more specialized pieces.
5:57
So, it might not be convincing to you yet
5:59
how amazing this is, so let's go and add
6:02
another one here for the package.
6:06
So, for packages we're going to have a couple of things
6:08
and I'm just going to copy a few bits here to start out.
6:12
So, we're going to have a blueprint
6:13
and it's going to be packages, that all looks good.
6:16
And this is going to be packages
6:20
what we want to have is maybe a details.
6:23
And we're not going to do anything super interesting yet
6:27
let's just return package details for some package.
6:34
And here do we get to define our first
6:37
interesting route, I guess I would say.
6:39
This is going to be, let's remind us
6:41
what that's going to look like.
6:42
pypi.org, the real thing
6:45
click on this one, it's going to be
6:48
/project/<package_name>, okay.
6:52
So that's what we want there
6:54
so here we say package, let's do package_name.
6:58
Like so. Now, notice start away that PyCharm is saying
7:03
whoa, whoa, whoa there's something wrong
7:05
with this part of your route. What is wrong?
7:08
A function index does not have a parameter to take it.
7:11
That's so cool. So, we just go in here and say
7:13
it takes a string, now it's happy
7:15
and we can actually put that there as well.
7:19
Okay. Let's omit that out for a moment.
7:23
So, we should be able to run this.
7:25
Let's change the name, let's call this
7:28
package_details.
7:30
And the blueprint, we're also going to have to
7:32
register this blueprint for it to work.
7:34
So, last thing, I need to go down here
7:38
to import package_views
7:43
like so and then we can import it
7:44
make sure everything's nice and cleaned up.
7:46
Did it rerun? Probably it did rerun.
7:49
Make sure, there we go.
7:51
So, we've got our two things here
7:53
but if we go to /project/abc
7:56
boom, package details for abc.
7:59
Okay, so we've defined our first interesting route
8:02
but maybe even more importantly for the moment is
8:05
we found a way to take our single super
8:09
mega monolith file that was defining our application
8:13
imagine there's fifty of these methods
8:15
and breaking them apart by category.
8:18
So, here we have home, these are the things
8:19
to do with like home and about.
8:21
And we'll have package and we'll have some
8:22
other package things going on here as well.
8:25
Of course we'll use that again in just a minute.
8:28
And then in our templates folder
8:29
I told you I was organize these
8:31
with this in mind so here we have home
8:33
we're also going to have a new folder called packages
8:37
in which case we're going to put our details.html.
8:41
So, let's just rob this one and call it
8:44
details.html, of course, it doesn't
8:48
have all the details yet, but it's going to.
8:50
So, this organization here is directly tied
8:54
to this organization that we did with blueprints there
8:57
so, I think this is a great way to organize your code
9:01
nothing about Flask encourages you
9:02
or suggests that you should do these
9:04
types of things, it's just a recommendation from me
9:07
you don't have to but I think it's going to be
9:09
really, really great as your app grows.