Building data-driven web apps with Flask and SQLAlchemy Transcripts
Chapter: Routing and URLs
Lecture: How to build a CMS in 8 minutes
0:00 I want to round out this chapter
0:01 by showing you just how incredibly powerful routing can be,
0:05 and I also want to dispel a myth.
0:07 Often, when people think about building web applications,
0:10 it's a decision between
0:12 should I use a CMS, a content management system,
0:14 something like Drupal or WordPress,
0:16 where I got an editing backend and I can type in the pages,
0:20 and it's just super easy for everyone.
0:22 Or should I create a data driven one like our example here.
0:26 We have a lot of packages in the data base
0:27 and each package gets it's own page.
0:29 Things like that.
0:31 And it's often presented as an either/or.
0:34 Either you have a CMS, or you have this data-driven web app.
0:37 I want to show you how we can use routing
0:40 to build a CMS in under 10 minutes.
0:43 I don't know how long it's going to actually take
0:44 'cause we're going to do it now live,
0:46 but it won't take very long.
0:48 By the time you've had the debate, the thing could be built.
0:52 That's not to say WordPress doesn't have it's place,
0:54 and there's not more to do
0:55 with what we're going to build here,
0:57 but just to show you,
0:58 there's a lot of flexibility.
0:59 So, let's get rolling.
1:00 Let's go over here and add a new file called a cms_view,
1:05 views plural, I guess, to stick with the others.
1:07 And then let's go over to our service
1:09 and we'll have a cms_service.
1:12 So, this is going to have the various data.
1:15 So, what I want to do is I'm going to define some fake data here.
1:18 So, imagine I want to find two pages,
1:21 company/history, that's going to show me
1:23 details about my company history, and company/employees,
1:26 it's going to be our team with pictures,
1:29 but you can easily fill this out.
1:31 So the way that it would really work
1:32 is you would have a database, you would create these,
1:34 maybe this is the primary key and then you would
1:37 fill out the details with some kind of editing
1:38 form you'd have to build.
1:40 So yeah, you couldn't do it yourself
1:41 in practice in 10 minutes, but it would be pretty close.
1:44 So what we're going to do is we're going to use this,
1:46 I'm going to have a function called get_page,
1:50 and it'll take a URL which is a string,
1:52 and it's going to return let's say a dictionary.
1:57 So the way it's going to work is it's going to be pretty simple,
1:59 we'll say if not your own return None,
2:02 I guess that makes the dictionary, something like that.
2:05 Anyway, so we'll return that and then we'll say
2:08 a page equals fake_db.geturl.
2:14 Maybe URL equals url.strip.lower,
2:17 and do a little normalization here.
2:20 And then we'll just return page.
2:23 And let's put an empty dictionary here as well for
2:25 our default value.
2:27 Either we're going to get that dictionary,
2:30 or we're going to get that empty one,
2:32 so it's the same as that.
2:34 Okay, so we've written this cms_service,
2:37 now what we want to do is that we want to go to our
2:39 CMS view, and let me just rob that from here,
2:43 something like that, so we're going to import flask,
2:47 we're going to say cms, that's all good,
2:50 this'll just be CMS page,
2:54 and this'll be CMS page.
2:58 So of course we need to be able to display
3:00 what we get back here, so let's go and create a new folder
3:05 over here, with cms,
3:07 and let's just borrow the about, like so.
3:12 Content here,
3:16 it's going to have a page title and a page details.
3:18 So the page title goes there,
3:19 and then maybe throw it into a div,
3:22 page, just copy to be sure, page details.
3:28 And don't care about that.
3:30 Okay, so there's the page that would display it,
3:33 maybe you want a little bit more,
3:34 but it's okay, we don't need this,
3:37 and then we need to go to our service,
3:40 which we're going to go over here to our cms_service,
3:43 and we'll get this.
3:46 We'll say CMS.get_page from the URL, what's that going to be?
3:52 Now we might not get a page back,
3:54 or maybe we will, so let's just return page here,
3:57 that's our dictionary, but we want to say
3:59 if not page, we've not talked about this,
4:03 how do you tell flask, or how do you have flask tell
4:06 the user 'Hey, this page or this thing is not here'
4:09 So it's super easy, we say flask.abort and
4:12 404, page not found.
4:14 And let's return that, so we return flask.abort,
4:18 and well this actually pretty much is it,
4:22 except that for the routing component,
4:23 remember that's what we're focused on,
4:25 so remember we were able to define stuff like,
4:28 I could come over here and say URL or something like
4:31 let's call it full_url,
4:33 and if I want that to be passed in,
4:35 I say this, well that doesn't match things like
4:38 a/b/c, it would match just like that
4:42 little element right there.
4:44 We saw before that we could say int and that would
4:46 make full_url and integer,
4:49 it's colored like this 'cause it's not being passed in.
4:53 But we don't want it to be an integer,
4:54 we want it to be a string,
4:56 we want it to be the whole path,
4:57 so the way you can do that is you can say the type here
4:59 is path, okay,
5:01 so let's just print beginning and CMS page for,
5:09 well I think maybe that's it,
5:11 we do have to register this blueprint back in our app,
5:14 so let's do one of these,
5:18 and one of these, and that's ready to go,
5:21 let's try running it.
5:22 I think it may work, unless I've made a mistake
5:24 while I'm talking and coding and all that.
5:27 So here's this, and we got our about,
5:29 we got our home, and these are all working,
5:31 but what if I go to company/history?
5:35 It's the moment of truth, what are we going to get?
5:38 Ah, not found, not found.
5:40 Getting company/history, and the reason is,
5:44 I remember we have the forward slash there
5:47 so let's do this, url = '/' + url.lstrip('/'), left strip.
5:58 Okay, so in case there's a slash there, we'll just leave it,
6:01 otherwise we're going to have it,
6:03 so now we try one more time,
6:04 company/history, give it to me!
6:06 Oh look at that, and employees.
6:13 Our team, company not there, 404.
6:20 404, so if you actually look at the request that came
6:23 in on the network or HTML, 404.
6:28 So not only is it give us this text,
6:29 it actually is giving the right status code back.
6:33 So if we go home, home, about, perfect,
6:37 we have our company, which is not specified in the CMS,
6:41 quote little baby CMS, history,
6:45 like so, that went and pulled it out,
6:47 so you can see, it's going for company,
6:49 but then it returned 404, I typed that in wrong,
6:51 then it got this one and said yeah,
6:53 that's a 200, here's your page.
6:55 Look at that, look at how ridiculously simple this is.
6:58 What is that, that's like eight lines of code there,
7:02 we of course have the database,
7:05 right, the databases I jammed in here,
7:07 but whatever, it's not much,
7:09 we had one line, or two to register
7:11 the blueprint, 'cause we are not jamming it all
7:13 in the one file,
7:14 and then we had one endpoint right here.
7:17 So, taking it in total that's like thirty lines of code,
7:20 plus a couple of lines of HTML,
7:23 and that's it to build this beautiful CMS.
7:26 And we just have to build a little backend
7:28 that lets people edit; like here's the title,
7:30 here's the URL, here's the content.
7:32 Right, we could easily do that, grab some open source
7:35 HTML editor, or better, markdown, let them enter markdown,
7:39 something like that.
7:41 This shows you both the power of routing,
7:44 and also if you're thinking about do I need a CMS
7:47 or do I need a data driven web app, it's not necessarily
7:50 one or the other, you could have a little of both, like this.