Building a Blog App With Flask and Flask-SQLAlchemy

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone its Anthony from pretty-pretty here in today's video I'll be building a blog so I'm going to take this template that I found online and here is the live version of this blog and I'm going to convert it to flask so I can actually add blog posts and then they will appear in this style that I have for this template so that's what this entire video is going to be about from start to finish I'm gonna approach this video like I would a normal project so instead of having everything pre-planned like I do for most of my videos I'm going to maybe have to look up some things along the way because I can't remember everything about every single thing that I write code for so before I get started writing the code there are three things that you can get out of the links in the description below the first will be the code for this video so after you're done watching the video you can get the code for this video there will be a link in the description below also you can get the flask cheat sheet this cheat sheet has a few things that are very common in flask so if you're somewhat new to flask or maybe you just want to see what I think is common you can download the flask cheat sheet so that's going to be in the description below as well and then also I have my website where I have full courses on flask and in these courses I have demo applications like I do like I'm going to build in this video so if you're interested in learning how to build more apps instead of just one-off videos like I usually do check out my courses on pretty pretty calm alright so to get started I have this blog let me close that out so here we have all the files that come along with the blog and then on the left hand side I have the beginning of my project directory since this blog is pretty simple I'll just keep it so one file but first I need to convert these HTML files to be templates in Jinja so what I'll do to start is I will create a templates directory so templates and then what I'll do is I will add the relevant files so contact abouts and then what I'll do is I'll just add the license here and then from here I'll figure out what CSS files are needed so let me get started with my app first thing I need to do is install flask so pip install flask this is a new virtual environment and up here I'll do the typical imports so app is name and then I'll put the if name equals main parts at the bottom down here so app run debug true okay so now that I have that what I want to do is I want to render the templates for those four files so I need to import render template and then I'll have four routes so the first route will be an index render template and I believe the file name is index.html yes and then I'll do the same thing for the other three so there's abouts and this one's going to be static so I won't have to really modify this one there will be posts and it's post I HTML I believe let me just verify that yes and then contact so those are the ones I'll start off with I'll need more especially to handle submitting blog posts but when I get to that you'll see what I do so contact render template contact dot HTML and of course since this is a view for all of them any return statements before them so let me just add the return statements here and now what I'll do is I'll start up the app so I can figure out which CSS files I need so first let me change directory to my project directory and then I'll start out the blog invalid syntax okay so I'll start it up and if I go to the index I get this so I have the HTML but I don't have the style so what I'll do is I'll open up all the HTML files and I'll start with the index and I'll take a look at what style sheet I need so first I need bootstrap so I will create a static directory in my project directory and I will add the CSS so it's in vendor bootstrap CSS bootstrap min so let's see if I can find that so vendor bootstrap CSS and then bootstrap dot min so I'll just take that and I'll copy it over so bootstrap min and then what I'll do is I'll change this to use the static directory so URL for static and then the file name will be bootstrap Minn dot CSS because that is what i just put into the static directory so now let me take a look at the app to make sure it actually loads so you can see it immediately changed so it's picking up some of it now I can move on to the next thing our font font awesome is the next thing I want to add in there so I'll find that font awesome CSS and then this is the minified version so I'll just take that one and copy it over so fun awesome and I'll do the same thing so URL for static and then file name is going to be font awesome mint CSS alright so I can skip over this because this is an external link same with this one and finally I have this clean blog min dot CSS so let me find that one and I'll simply add that to my project and I'll do the same thing so it's going to be URL for static and then the file name is going to be that clean blog and let me just cut and paste here so cut paste and that should be it so let's see if this changes again alright so now I have more of the look it's not completely done but it's almost there so now I'm going to look for any JavaScript in here that I need to modify so it should be at the bottom uh so jQuery popper and bootstrap along with clean blog min CSS so all these are going to be very similar so what I did for the CSS so I'll just add them all at once so j/s clean blog and then I'll also go to the vendor and jQuery is one the minified version of jQuery popper is another and there's a bootstrap one so simply bootstrap dot min and CSS all right there we go so now what I want to do is at the URL for all of these and I'll just copy one from up here because it's going to be very similar so I'll just take this copy it and I'll put it here for each one at the beginning and then I'll modify the actual file names so for that one I can put the J s there and I'm not copying the paths just the files so I can get rid of the path and then popper and jQuery okay so now let me refresh and make sure everything looks okay and it does so finally what I want to do is I want to find the images so I'll search for IMG tags and what I'll do is I'll replace these with URL 4 so in this case I'm looking for an image and it is home background so I'll put that there and then once again URL for static file a name is going to be home background dot JPEG and make let me make sure that I'm using the correct brackets so I have double brackets there let's see if that works it doesn't so just something here is messed up so let me copy the URL for and I'll undo everything and simply replace it okay so single quotes here and then double quotes for the HTML so what I'll do is I'll set a variable actually no I don't want a variable I will just put it here I'll put double quotes here and let's see if that works it doesn't so just the quotes here so I have to find out how to escape quotes in Jinja so this is the first thing I need to look up because I don't usually do this so let's see I got a stack overflow and I'll look for an answer an actually single coat should work pretty well because what happens in the URL for it gets rendered first so let's see I just have to make sure that it doesn't close it out and properly there we go so let's take a look now there we go so I have the background for the blog there I'm missing something here maybe it's the fonts so let's take a look yes it's fun awesome so maybe that's not loading correctly so I will refresh and take a look and see if there are any 404 errors so yeah I have 404 is for the font awesome get requests so let's take a look and see what's going wrong there I don't see anything wrong so far is it loading the original font awesome yes it is and it's loading these but fun awesome dot web fronts ok so let's see if I'm just missing those files from the static directory so I'll go back to vendor font awesome and then fonts and I'll simply copy this over and let's see if it can pick it up and I'll know if it picked it up because the fonts at the bottom will start working so still nothing so let me find the reference to the fonts so here we go here's the problem it is up to directories so if I just remove those extra dots and by removing these it should be able to pick them up and let me make sure there are no more they should be at the beginning so I'll try that and let's see if it changes still nothing so let me look for URLs how about a hard refresh so the CSS loads again still not there so what I'll do is I'll ignore this for now sorry don't spend too much time on that and I'll come back to it later so now that I have this set up I want to move on to the next pages so I'll close this out and the links should be the same for the other files as well so we see bootstrap font awesome and then clean blog so I'll just copy and paste that over so from there to there and I'll do the same thing for contact and post all right and then what I want to do at the bottom is change the JavaScript so I'll go to the bottom of this file and copy it over now I could have these in a separate file than include them but since I only have four files I don't think that's such a big deal and this one has some extra so what I'll do is I'll ignore that one for now well put it below and then bootstrap validation and contact me ideas so actually I don't want to use those for this app so I'll get rid of those because it calls a PHP script one that I won't be using so now let me check the other pages to make sure they look okay so about two posts in contact so about it looks fine except for the fonts there and the background image so let me fix the background image for abouts I'll search for an image tag IMG and then what I'll do is I'll put a URL for in there so I'll just copy the one I have here so I don't mess up the quotes again and URL is going to be this and it's going to be about BG instead of home BG so I can remove that save it refresh still doesn't work because I did not copy over the image so abouts then refresh okay so that's there and this page is going to be left alone because there's just a static page so now post and I'll get the background for this one so post and where's the background here we go so I'll just put that there I'll copy URL for again go to posts paste it in there change this to post background and then delete the old link and then I'll copy it over so post background and then I'll refresh okay so this page works and the fonts are messed up and the fonts are just social links thinking about it so I can remove those so the contact me page is the last one so for the image I will copy and paste this and then change this to contact background JPEG and then copy over the image and refresh okay so now let me remove the social links because I don't need them and they're messing up so the social links start in the footer let's see need to find where they end looks like this unordered list so I'll simply remove this one and let's take a look at the contact page now so I want these to disappear alright those are going and then I'll do the same thing for the other three pages and then once I'm done with that I'll pretty much be done with modifying the templates to be supported in flask so posts about I'll remove the social links and then the index okay so now what I'll do is I'll go back to the index and I see I have everything looking good the social links are going I need to modify these links to point to the correct page so I'll do that now so now what I'm looking for is any HTML reference because that's pointing to an actual template instead of the page so what I'll do is I'll add a URL for here so the main content that's a little different that's going to be dynamic so I can skip over that but once I get to the links in the navigation so like this one this should be URL for index and then likewise for this one down here and then I'll add about post in contact so these just match the routes that I've created already so now let me make sure that these work so just looking at the address that shows up on my browser those all look ok and the navigation is the same on each one so what I'll do is I'll just copy and paste like I said if you had more templates then you probably want to create a separate file to include them but since this app is going to be pretty small I just want to keep it as simple as possible so once I do this I can get into the actual good stuff so as you can see it doesn't take much to convert a template but if you are starting with a template which could be normal if you depend on a designer to design how your app will look then yeah you have to convert the template to be used in Jinja and flask so now that that's done like if I go to sample posts and then about all right so all these links are working correctly so now the first thing that I want to do is I want to set up a database so what I'll do is I'll use flash eco alchemy flask underscore sequel alchemy and I need to install that using pip so it's being installed so from flask sequel alchemy import sequel alchemy and my app configuration needs a database location so database URI and then Sieg welcome egos in front of it so sequa alchemy database URI sequel light and then I'll specify the location and I'll call the database blog DB all right so once Eagle alchemy is done installing I'll create the database so blog DB call tables so it saves the database and now I should have a database there so I see the blog DB there so now what I want to do is I want to create a table that will hold the blog post information so class I'll call this post say blog posts inherits DB model first one is going to be an ID so ID is going to be an integer and this should be DB column first so DB column and then an integer and it will be the primary key second one is going to be a title so let's just have that be a string of 50 characters next will be a subtitle because looking at the blog that I have let me go back it has a main title and then a subtitle down there so a subtitle will be same it can be 50 characters as well and then I have posted by so author and I won't create a system of authors I'll just keep this simple and have it to where you can input an author so author it's going to be a column and it's also going to be a string and let's say 20 characters for the author next the date post it so dates post it it's going to be a column and then let me look up flat sequel alchemy Docs because I want to know exactly which columns I can use so if I can spell sequel alchemy I'll look it up in the documentation I just want to make sure I get the column right because there are different types of columns that I can use so declaring models and then there should be a section here yes Oh date time so DB day time and then I convert can and convert the date that gets stored there into a regular date so I'll handle that later so DB date time and then the last thing of course will be the actual content of the blog posts so I don't want to string I want something bigger so some longer Unicode text will be DV dot X so I'll call this content is DB column and then DV dot text and let me start up my app again just so I can see the contact page make sure I'm not missing anything so I have a title a sub title an author a date and the constant in the article so that's exactly what I want so now that I have all those things what I want to do is I want to actually create them in the database so I'll start up Python and then from app import DB DB create all and there we go so the database should have that table now and it's going to be the one table for my app because it's simply a blog if you were to have authors then you have like an author table and any other extra functionality that you want to have you might have to have a corresponding table but for this example I'll keep it pretty simple because I'm already 30 minutes in and I'm only getting to the database so I don't want to do too much but I have the one table that I need and if I need to do something else then I can come back to it later so now what I want to do is I want to enable the user to add blog post to the database so first I'll add post to the database and then I'll actually display them so what I'll do is I will create a new route and I'll call this ad so Edie will be a new template at HTML but since contact already has somewhat of a form so I'll start up the app again what I'll do is I'll use this form to submit the blog posts and I'll change this up a little bit but it's going to be in a similar style so contact is going to be uses add HTML and then what I want to do is I want to remove the contact me and I'll replace it with add post so let's see if I can find it contact me at posts you can create a blog post here so I'll refresh this and it's my app running looks like it is star refresh and I'm looking at the wrong page so I need to go to add and I see add posts and then I'll modify this form to accept the necessary things that get stored in the database so like the title the subtitle and so on so what I'll do and add here is I'll remove some of the things like the ones to get in touch with me part I can simply remove that so I remove all this and then I'll have a title and I'll change the name to be title please enter a title and then I'll have a subtitle and this will be typed text placeholder will be subtitle ID will be subtitle and the name should be subtitle so I'll add a name here because when you submit a form it uses the name instead of the ID so subtitle and then for my title up here I need a name as well title so let's see if that looks ok so far all right so title and subtitle are there so now the next thing I want to add is an author so the third one so instead of a phone number I'll change that to be author so add and then let's see where is it author is here type is going to be text again placeholder will be author name will be author an ID will be author and finally I'll change this to blog contents play soda will be blog content a message will be or the ID will be content and the name will be content so let's see all right so everything looks good so far and then I have this in button the send button that doesn't do anything yet so now what I want to do is I want to add a route to handle the submission of that form so what I'll do is I'll have it submit to a route called add posts add posts and I need to import the requests from flask so I can actually get the request data and now what I want to do here just to verify that it works is I want to show all the information that's being passed in so title is going to be blank and I'll fill this in in a moment title subtitle title subtitle author and content and then I'll close out the h1 and then our format this width so I'll create variables here so title is going to be requests that form title subtitle is going to be pretty much the same subtitle and then I'll use author so author will be request form author and finally content will be requests data form content all right so I'll pass all these in so title subtitle author and content and then I need to modify the form just a little more so where is it the the form here I need to call this add form add form and then the method will be post and the action will be URL for URL for ad posts so now let's see if all this works correctly if it does then I'll be able to see what I pass in if it doesn't then I'll probably get an error so let me refresh this remove the query variables I got an error because I saved too early so I just restarted the app I'll go back to ad so the title will be the title the subtitle will be the subtitle the author will be the author and here is the blog content so if I send this I'm hoping to see it and it tells me method not allowed so that's a pretty easy error to fix I forgot to put methods to be post because by default it's gets so I'll go back and I'll try this again and now I see all the data that I want so I see the title I see the subtitle I see the author and I see the content so that's exactly what I want so now that I can do that I want to add all this to the database so I have this blog post so I'll creates variable called post and now instantiate blog posts so the title will be the title the subtitle will be the subtitle the author will be the author and the content will be content so I can remove this down here and I'll return redirecting the user to the index so return URL for where is it just redirect no it's redirect first in the URL for and then the etics so I need to include redirect in URL for okay so in addition to the title subtitle author and content I also want to have the date posted so I'm going to need to import the Python daytime object so from date/time import date/time I believe that's it so to test this out what I'll do is I'll use my console or the repple so from date/time import date time and then date/time dot now and that's exactly what I want so it shows me the time that it is right now and I'll just pass that into the database so I'll exit and I'll start up the app again so date post it will be date/time that now okay so if all this works correctly then I'll be able to look in my database and see that I posted a blog post so before I do that let me take a look at the format of the post here so I can kind of write it in a similar way so it's going to go in between this div so it's just paragraphs block quotes and headers so this won't be a fancy blog with like a rich text editor it's going to be pretty simple so I have to add the HTML myself so now let's take a look so the title will be first blog posts subtitle will be I hope this works author will be Anthony and the blog content will be this is the first blog posts on the site now in that there and then I add another paragraph I hope all this works well alright so there's the information I want so when I hit Send it should save it to the database but one last thing I forgot to do is I actually have to add it to the database so I'm creating the posts but I'm not actually adding it to the database so to do that with the sequel alchemy it's pretty simple DB session add posts and then DB session commit and then the post should be at it and then it will redirect me to the index so let's see if that works send then I get redirected to the index so now to figure out if it works properly what I want to do is I want to open up sequel Lite so blog DB and I'll select star from well what's the name of the table that I have blog post so select star from blog posts and you can see it has an ID of one then I have the title that I added I have the subtitle the author me the date/time and then I have the content so you see there's two paragraphs there and that's it so I know that adding opposed works so now that I can add a post what I want to do is I want to actually show all the posts that I have but will actually know I want to show the actual post here so I'll replace this with a title this with a subtitle and so on and then the content here so I'll go to my post template and I'll modify it a little bit so I'll change everything inside of the div that I just mentioned so from here and let me just follow it down because this is well spaced so I can simply get rid of all this here because this is the content all right and then I'll replace that so in the posts what I'll do is I'll allow for a post ID so it's going to be an integer and I'll call the variable post ID and to use that I need to include it here post ID and then what I'll do with that post ID is I'll query the database for it and get the actual post content for whatever posts I pass in so for the first post I have one but for other posts it can be something else so this will be a query so it's going to be blog post doc query dot filter by and then ID equals post ID and this can be a get but I'm so used to filter by that it really doesn't matter and there's going to be one result because the post ID is unique so with that I can pass the post to the template and then I can modify the post here so the title will be post spot title and let me try that out so I have posts here I need to specify the URL now so post last one and it says it could not build URL for endpoint posts so it's telling me that I've forgot something so let's see posts there's a post ID here and it's just asking me if I forgot the posts and the reason why is because I no longer have that link to the post so what I'll do is I'll remove the sample post link because it doesn't make sense anymore so I'll go to posts and I'll do that on the other ones as well when I get around to it so remove posts and then refresh okay so now I see the first blog post and then the content is gone because I removed it so let me replace the subtitle and the author so where it is okay so this is the subtitle so post subtitle will give me the subtitle information and then post it by I don't need a link so I'll simply remove that and I'll put post stop author so let's see if that works okay so first blog post I hope this works posted by Anthony on August 24th 2017 that's not dynamic it so I'll have to change that but let me at the content here so if I simply do post content that should give me the text and Jinja is showing these because it's escaping so to not have that happen I just type safe after the content and then you can see if formats correctly so this is just to protect you from people typing in HTML and then you loading it into a template directly if you know that there's going to be HTML and something that you're loading then you just pass it through safe and then you can see it that way so now what I want to do is I want to actually show the date so I'm recording this on September 3rd so instead of August 24th it should be September 3rd so what I'll do is I'll look up how to display the date time so Python convert date time to string because this is something that I don't do normally so it's formatting the time so I have the date time and what I'll do is instead of doing it in the template I'll have to modify it and Python so they post it will be a variable that I'm going to pass the template so date post it equals date post it and just as a test let's say January 28th 1950 and if I go to post here and change the date too they post it I should see that January 28th ok so that part works so now I want to use the actual date not just a hard-coded date so I need to convert this using what I see here on stackoverflow so there's this string.format time so stir f time strf time so I have my posts dot date posted then I'll call stir F time on it and I'll give it a format so the format will be let's start with simply the month so it should be a number month if this works if it doesn't I may have to modify something ok so oh 9 so that is definitely the month of September so let's see if capital M gives me the month name it doesn't that's the date so let me look at this formatting link and what I'm looking for is the month spelled out so that's % B which is not intuitive at all so percent B gives me the month alright and then I want the day so I think as percent D yes and then a comma and then the year so percents and then let me look up what the year would be so let's see where is the Year percent capital y ok so now I see everything that I want to see I see the title the subtitle who posted it when it was posted and the actual content of the posts so just thinking about it now I'm not going to do anything with the contact form so I'll remove all that from my project so templates I'll remove contact here and then I'll remove the static contents background or contact background and I can close this out because I have all the things that I need so on posts I'll remove that contact link that can be a video for another day and then on add same thing I want to remove the sample post and the contact contact is gone about remove the sample post in the contact and on index I'll remove the sample posts and the contact all right so refreshing so I only have two links now which is what I want so if I go back home now what I want to do is I want to get a list of all these and I won't use older posts because I won't have any post in the database so I'll leave that button there but it won't do anything instead it what I'll do is I'll simply loop through the post in the database and I will display them here so before I do that let me add a second one so it's easy to see 2nd posts here is the second posts author is Anthony again and then the blog content will be just do a header here is the second posts this should work because I already tested it with the first post all right so I'll add this and it returns me here so I know that post was just committed to the database because I tried it with the first one so if I go back to posts and go to number 2 because it should be 2 it's sequential then I see my second post and if I go 1 and then I'll see the first pose so now what I want to do is I want to loop over the results and display them on the index so I'll remove contact here because I'm not using it anymore and then I'll go to index and what I'll do is I'll create a variable called posts which will represent all the posts in the database and then now use blog posts query and I won't filter by anything because I want all of them and I'll pass these to the database or pass them to the template so now what I want to do is I want to go to the index here and fine wear it loops so you can see that this hTML is repeated over and over again so I just need to remove all but one so I'll remove this one and there's a horizontal row in between so there should be three more to remove and I just need to make sure I don't remove the last one all right there we go so in here what I'll do is I'll create a loop so for post and posts because it's passed to the template in for now what I want to do is I want to replace everything so manless Explorer that's the title so this will be posts dot title so let me just verify that part works all right sorry see first post in second posts and then there's a link so I want that link to point to the ID so this link will be URL for posts and then I need to pass in an ID so the ID will be posts ID so if i refresh this and then it's telling me there's an air that's because it should be post ID not simply ID so post underscore ID all right so I can see them in the browser so if I click here I get to the second post and if I click the first blog post then I see that again all right so now let me add this subtitle subtitle posted by so once again I don't eat the link post dot author and I won't be able to get away with doing that same trick where I format the dates on the Python site so first let me make sure everything looks good all right so I hope this works and here's the second post alright so I have everything except the actual date and you saw before I use the trick where I did it in Python because start as time is something that you can only call in Python but just to be sure let me try this so I'll copy that and inside of the template I'll do this and let's see how much it complains and it doesn't actually so that works so what I'll do is I'll do the same thing on the posts and now remove the date posted here so I didn't eat that I can do the string format of time and it's probably because it's an it's a method of the day posted date/time object so yeah that's why it works so now everything looks good I can click here they post is not defined because I just messed that up so if I remove date posted here I should be able to see there's the second post so everything looks good like I said this older post button won't do anything let me just remove that because I don't use it for anything so move that and yeah so everything looks good like I said I have the index which I was just looking at the about page was just a static page I have the add page and then I have a post page so really the last thing I want to do is I want to add that link to the add page on the home page so I'll add a link there and I'll call this ad ad and I'll copy this for the other templates ad here and up here and then refresh okay so I see ad and I'll add one more post third posts this is the third posts author out changes to be David blog content here is the third posts it looks like everything works well with this blog so I'll send that and then you can see the third post there so everything works well and maybe one last thing I'll do is I'll order this so instead of being ordered by the oldest posts to the newest it will be newest to oldest like a typical blog so I will go down to the query for the posts here and I just need to order by date post it so blog posts dot date underscore post it blog post dots date posted dot ah so let me make sure that works and I think I saved too early yeah so Python app all right so yet still works so it should be DB dot descending so I can't remember exactly how to do that in Flast sequel alchemy so I'll look that up and it should be pretty simple yes it is so just simply dot d s C and now if i refresh it orders by the newest to the oldest so that's just about an hour to build this very simple blog but I hope that by watching this you can kind of understand the process that she will go through to build a typical app I mean in a real app there would be a lot of other things that you have to include I skipped a bunch of things in the interest of time but this is basically the process that I go through as the file grows larger I like to organize it better but I knew this would be a pretty small app and this is what only 54 lines of code to create this blog so you can see that it really doesn't take that much to do it so that's it for this video like I said if you want the cheat sheet this here just click the link in the description below it's flask or a pretty pretty calm slash flask cheat sheet then you can go to my website where you can take other courses on flask and finally in the description below I'll have all this code for you to take a look at just in case you want to modify it or start here and see what you can do to it so if you have any questions you can leave a comment down below if you like this video please give me a thumbs up and if you haven't subscribed to my channel already please subscribe so thank you for watching this video and I will talk to you next time
Info
Channel: Pretty Printed
Views: 58,587
Rating: 4.9057899 out of 5
Keywords: flask, flask-sqlalchemy, blog, app, blog app, build blog with flask, create blog with flask, sqlalchemy
Id: XHGpPCYmPvI
Channel Id: undefined
Length: 57min 24sec (3444 seconds)
Published: Sun Sep 03 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.