Python Blog Tutorial #3 - Creating And Deleting Posts
Key Takeaways
This video tutorial series covers creating and deleting posts in a Python blog, utilizing tools such as Flask or Django for the backend and HTML/CSS for the frontend.
Full Transcript
hello everybody and welcome to the third video in this flask blog tutorial series in this video i'm going to be showing you how we can actually create posts so how users can sign in create a post and then have all of those posts showing up on the home page of the blog i'll also show you how we can view all of individual users posts so let's say i have like six or seven different posts you can click on my name and you'll see all of the posts simply by me so with that said let's dive in all right so right now we have a working login and signed up page however we have a very small error and i just realized this after filming this intro so right now i'm actually signed in you can see that because i can access the home page but it's only showing me the login and sign up kind of buttons in this navbar now that doesn't really make much sense if the user is logged in i probably shouldn't show them these two i should show them the log out button and so what i'm going to start by doing is just making this nav bar only show the login and sign up button if the user is not logged in and if the user is logged in then what i will do is show the log out button instead then after that just to give you kind of a vision of what we're going to do here i want to turn this home page into kind of the main page of the blog so when you go here you'll see everybody else's posts so just in chronological like time order you'll see all of the posts that all users have made and then what you can do is you can click on a user's username and you'll be able to view all of their posts kind of like their blog this will be kind of a half blog half social media site regardless just wanted to show you or tell you that's kind of the vision for this tutorial right here okay so first thing we need to do is change that nav bar so i'm going to go to templates and base.html and inside of here i'm going to start changing some of the stuff on the navbar so notice right now i have home login and sign up now what i want to do is add a log out button and so i'll just add one right here and we will say that this is going to go to log out and this will say log out now what i can do inside of here is i can actually check if the current user that i have is logged in or not so what we'll do is we'll check if the current user is logged in if they're logged in then we will show the logout and home button otherwise we will show the login and sign up button so what i'm going to do here is put an if statement and i'm going to say percent percent if user dot is underscore authenticated i don't know if i spelled that correctly okay let's do that then percent percent and if so we'll do this oops if i could type properly and then i'm going to put in else here and then i'll just rearrange where i have these nav items so i always want to show this home button so we can do that right here and then if the user is authenticated i don't want to show login instead i want to show log out so i will put log out inside of the main body of the if statement and then inside of the else here i will show the login and sign up so if the user is authenticated then we will show log out and we'll always be showing home otherwise we will simply show login and sign up nice okay so that should hopefully work for us now but notice that i called or used this user variable and i'm not necessarily passing this user variable to this template so i need to make sure i'm doing that so what i'm going to do now is go to my views so auth and views.pi will start inside of auth and what i'm going to do is pass to the render template the variable user so i'm going to say user is equal to and this is going to be current user like that so when i do this this will pass the user object that represents the currently logged in or not logged in user and then inside of here i can do this check and check if the user is authenticated now when i check is authenticated that simply tells me is the user logged in or are they not logged in obviously if they're logged in this will be true if they're not logged in this will be false so this comes from flask login notice how i imported current user up here so we need to make sure in all of our views we're passing user equals current user so what i'm going to do is go down here to sign up same thing i'm going to pass user equals current user we don't need to do it in logout because we're just having a redirect but if we go to views.pi okay we have name but instead i'm just going to make this user is equal to currentuser okay so now we should be passing the current user in all of our views so if i go back here and i refresh okay it logged me out because i refreshed there notice it's showing log in and sign up let's log in here i made an account which is tim gmail.com and then my password will be this okay uh email does not exist okay give me one second guys all right sorry about the cut there guys but i realized we have a small error very easy fix but essentially any account that we created during one run of our website was instantly deleted after the website was reran or the server was reran because we weren't actually creating a database our database was simply being stored in memory and then as soon as the app reran all of the accounts that we created well they just disappeared and were deleted that's because i had a very small smell uh spelling mistake here sorry inside of a knit dot pie notice how this says sql underscore alchemy this needs to be sql alchemy so no spaces i've made that mistake a few times now so now when i save this notice that this re-ran and we actually see this database.db file so you probably may have noticed that in the previous tutorial it wasn't actually creating this file now we have this file and so when the application is rerun we should actually have all of the accounts that we created still created and stored in the database so let me just make a new account here because obviously my account's gone now so we're gonna say tim gmail.com tim one two three four five six seven and one two three four five six seven okay so sign up user created now notice it's showing me home and log out it's not showing me the sign in and sign up so if i press log out please log into axis's page i guess because it redirected me to the home page and now what i can do is log in so tim gmail.com one two three four five six seven log in and then notice it's showing me these right here perfect okay so that is all good nice so now that we've fixed those small errors right there we can actually get started on creating posts so the first thing i want to do to create a post is make an html form here that allows us to actually well make the post so i'm going to make this on a separate page and what i'm going to have is a button on the home page that says create a post and when you press create a post then it will redirect you to this page will just be a very simple form which is a text box and a button and you can just type out what you want and we'll make a post now you guys could add images to this and other attachments and stuff in the future if you want but for now we're just going to do simply text all right so to do this we need to create a form let me just go to my cheat sheet here to make sure i don't mess this up so actually the first thing we'll do is make an h1 tag this h1 tag can be in the center of the screen so we'll say line equals center and then quite simply we will say make a post and i believe center here needs to be lowercase alright so make a post that will be our h1 tag we're then going to make a form the method is going to be equal to post because we're going to post data to our backend so let's end the form here and then inside of the form we're going to put a text area so text area name is going to be equal to text the id will be equal to text and the class will be equal to form hyphen control that's a bootstrap class all right we can end the text area so oops slash text area like that nice now we're going to do a break line uh just to make sure we go down to the next line and there's some spacing i'm now going to make a div this div is going to be aligned in the center and then inside of here we're going to put a button so we'll say button like that we will end the button and then the type will be equal to and this will be sorry submit and the class will be equal to btn btn hyphen lg and then vtn hyphen primary to make that a nice blue color this button will say post and then we will end the div here and save and i think that's all we need so let me just check here make sure i didn't mess anything up i think we are all good all right so this is the html for our create a post page now we need to make a view for this so that we can actually render this page so let's go to views.pi let's go at views.root we can call this create hyphen post or slash create post and then this will be at login required as well you can't make a post unless you're logged in define this will be create underscore post and here what we will do is actually say that the methods allowed for this will be get and post because we want to be able to get the html of the page we also want to be able to post data to this view that data will be the text that makes up the post from the user right so let's just start by returning the html so return render template name of our template here is create underscore post dot html and then we need to make sure we pass our user so user is equal to current user all right so that's all we need for right now so let's rerun our application and let's see if this works so let's go here let's refresh notice i'm still signed in because now my database is actually saved and if i go to slash create hyphen post like that it brings me to the make a post page of a text area and i can press post awesome okay so now we need to handle what happens when you press post so the only piece of data we have is our text so we just need to grab that from the form attribute of our request when the method here is post we're going to say if request dot method equals equals post we're going to make sure we import request from the top of our program here so if request.method equals equals post then we're going to say the text is equal to request dot form dot get and this will be text okay we're then going to make sure that we actually have some text so we'll say if not text then what we want to do is flash the message saying let's say post cannot be empty and the category is going to be equal to error we need to make sure we import flash so let's import that right there so if that's the case we will flash that otherwise that means we do actually have some text so we need to create a new post using this text so for now i'm just going to flash a message saying post created exclamation point the category will be equal to success nice okay so we will now actually end up creating a post but to create a post we need a database model that's going to store the post so let's go back to models.pi and now we're going to make a model that will represent our post so we're going to say class post this needs to inherit from db.model notice how i'm not inheriting from user mixin that's because this was a special class we only inherited from from our user class that we're using to sign in and log out users in this case we'll just have a regular database model this is called post and now we need to uh what does it define all of the columns or fields that each post is going to have so we have to think about this for a second what do we want each post to have on it well first we need an id so we can copy this because this is going to be the same for all of our database models we need an id that is unique that is the primary key then what else do we need well we need the text associated with a post so i'll say text is equal to and then db dot column this will be db dot text and uh this will be what do i want to say here nullable equals false so this just means we must have some text you can't have no text associated with a post then after that so after we have our id and our text we probably want the date that this post was created at so let's do that date created we can just copy this field right here and then lastly we need a user that created this post right we need to know who was the actual author of this post so we'll say author is equal to db dot and then this is where it gets a little bit tricky this is where i'm going to talk to you about something called foreign keys all right so let's talk about foreign keys and how you can actually relate database models and tables together so as i was saying we need some author that made this post the thing is though i need to make sure that the author actually exists right because what i could do is i could do something like db.column and then db.integer and maybe this column here is just going to store an integer that represents the id of the user who created this post now that would work i could just put the id of the user and then i would be able to access the user using its id but this does not enforce that the user actually exists when i create a post so what i mean by that is i could make a post and i could pass for author some random integer representing the id of a user but that user may not actually exist so that's kind of one problem that you're going to run into there another problem is that i don't really have a good way to find all of the posts that a user has created if i do it in this way so if i just do this i just store the id of the user i can find all of the posts that the users created but it's a lot less inefficient or sorry a lot less efficient not a lot less inefficient and while i'm going to show you kind of the proper way to actually relate two tables together because ideally from the post i want to be able to access the user and all of the information related to the user and from the user i want to be able to access all of its posts so this is where we talk about foreign key and what's known as a relationship so what i'm going to do here say author is equal to db.column db.integer but then i'm going to add a foreign key okay so foreign key like this so i think it's foreign is it like that or is it underscore key i gotta check no this is correct so db.foreign key and then what i'm going to do is put the name of the table and the field in the table that this foreign key is going to reference so i'm going to say user dot id so by default even though this class name has an upper case inside of the actual database this will be represented with a lowercase so this table name in our actual sql database is lowercase user not uppercase user and so i'm accessing the table using a lowercase so user that's referencing the table and then id is referencing the id field in that table so i'm saying whatever integer is here must match one integer on the user table in the id field so i know which user created this post then what i also need to do here is add something called on delete so i'm going to say on delete is equal to and then cascade and just cascade need to be in capitals yes it does so we're going to go cascade like that so what this is saying is when i delete the user that this table is referencing i want to cascade and delete all of the posts that this user has so that's what this ondelete is doing if you don't add this you will have posts associated with a user that has been deleted so let's just make sure if the user gets deleted all of the posts that the user has gets deleted as well and then the last thing i need to add here is nullable equals false just to make sure this table must have a value and it cannot be null okay so that is the author field so i've added the author field and by doing this now i'm able to access the user who created this post but from the user i want to access all of their posts so now what i need to do is create something known as a relationship so i'm going to say post notice how this is plural is equal to db.column and inside of this column or sorry it's actually not db.com it's db.relationship inside of here what i'm going to do is put the name of the table that this post is referencing so in this case it's going to be post like that and then i'm going to add the two following things back graph is going to be equal to user i'll describe what this is in one second and then i got to look here i'm going to add this passive oops like this underscore deletes with plural is equal to true so let me describe what i just did here so on the user model or on the user database table i'm now adding a new column called posts now this column is going to be a relationship and what that means is this is going to reference all of the posts that this user has so any post that has the author which is equal to the id of the current user there will now be kind of an addition on this user table that references all of the posts that this user has created so that's why the relationship is going to post now what is the back ref well a back graph stands for back reference and this means from the post how do i access the user object that created the post well what i do is i use dot user this is a little bit confusing but by adding this back reference what this allows you to do is rather than using this author field here to access the id of the user it allows you to actually write something like post dot user so let's say we had some posts created we have p or p is equal to post and let's say we filled in all of the values that we need okay now if i want to access the user that owns this post i can do p dot user and this actually gives me access to all of this whereas if i did p dot id this would give me some integer not the actual user model itself hopefully that kind of makes sense but that is what back reference does and we'll use this in a minute and then passive deletes this kind of goes hand in hand with the cascade thing this allows all of the posts to be deleted when this user object is deleted so if you want to make sure that's the case that all posts get deleted when the author of those posts is deleted you need passive deletes equals true and on delete equals cascade okay so that's about the best explanation i can give you if you don't fully understand it that's fine but this is how we set up a relationship a one-to-many relationship one user has many posts awesome okay so let's continue now so now that we've created this model what i need to do is go back to init.pi and i need to import this from my model so that it's created when i create my database so from.models import user and import post okay now we're going to go to model stop pi or sorry views dot pi and we're going to say from dot models import post and now what i'm going to do is when i have my create post here and i actually get some valid text i'm going to create a new post so i'm going to say post is equal to post i'm going to say that the text is equal to the text i'm going to say that the author is equal to and this will be current user dot id and i believe that's all i need i don't think there was anything else we had on this post model no date created an id will automatically be generated for us so now that i've created the post i need to add it to my session so i'm going to say db dot session dot add and i'm going to add the post and then db dot session dot commit to actually save the post in the database before i do that though i need to import db so i'm going to say from dot import db and now i have access to that database object so i can actually use this so that should actually create the post for us so let's go ahead and try this out i'm going to go to python dot slash app.pi i'm going to now go back here refresh okay so let's just press enter like that and let's see what happens now if i actually type something in so hello my name is tim okay i press post and we get some errors there's no such table post so the reason i'm getting this error here is because we need to recreate the database because this database here is kind of stale it has only the user model in it and the reason it only has the user model in it is because we haven't recreated the database when the server reran because it already exists so if you look at init.pi here we have this function this function creates the database for us but it checks first if the path already exists so what we need to do is delete this database so we just manually delete it and then we're going to refresh our app here so let's just stop this and re-run it and now the database should be recreated and this time it should create the post table hopefully that makes sense but whenever you get that type of error just manually delete the database and then rerun the app and it should recreate it so if you're adding or changing around all of the models and stuff you'll have to do that there's other ways to get around that but for now this is kind of the easiest way so if i refresh this now and i continue the form resubmission okay i've got to log in so let's actually create account because we've deleted the database so tim gmail.com tim and this will be one two three four five six seven one two three four five six seven sign up user created okay let's make a post so slash create hyphen post okay let's go hello my name is tim let's press post and then it created the post awesome so that actually worked we got that flashed message now we need to actually view the posts and we want to redirect the user back to the home page when they actually create their post so let's go ahead and do that okay so let's go back to views.pi we've now created the post and after we create this post here and we flash the message let's return a redirect okay to the url underscore four and this will be views dot home like that okay so we now need to import both re direct and url underscore four okay and that's fine and what were we going to do next we now want to view all of the posts on the home page all right so what i'm going to do now is inside of the home page when we go to the home page i'm going to get all of the posts the way i'm going to do that is by saying posts is equal to and this is going to be post dot query dot and actually i think i can do all um yeah we'll do post.query.all let me check if that is correct okay so that is correct and then what i want to do is pass all of these posts to this template right here so i can then access them inside of the base template so what i'm going to do is say post is equal to posts so now inside of the home template i should have access to the variable posts and i can start looping through all of the posts and showing them on the screen so we'll make this look nicer in a minute but for now let's just see if we can actually view these posts so we can test if this is working or not so let's go to home.html and inside of the content block here we're going to start viewing all of the posts so we're going to make a for loop we're going to say percent percent for post in posts we're going to end the 4 and then we're going to see if we can just view the post.text so we're going to go like this and say post dot txt now this may not work but it also may work let's see if it does so let's just go here and refresh oops we want to get so we'll do that and then go back to the home page and there we go we get hello my name is tim so we actually are able to view the post nice now obviously there's some more things that we want to view associated with each post but for now that's pretty good so let's now see if we can also view maybe the author of the post so that's the post text but after we view the post text how can we view maybe the username of the person who posts this well what we can do is say post dot user dot and then username so if we do that and we refresh here node says hello my name is tim and then the username of the person who created the post is tim we access that by saying post.user.username now notice if we just did post.author like that what this would give us is the id of the user who was the author of this post so just keep that in mind that's kind of the difference there nice so that is all working now that we've done that i want to view these posts a little bit nicer right i want a nice little box for them i want the date they were posted at i want to actually see the username so let's start writing some html to actually view the post in kind of a nice format so we will continue in one second we need to thank the sponsor of this video and this series which is algo expert algo expert is the best platform to use when preparing for your software engineering coding interviews they have 160 coding interview practice questions which really are the best resources to prepare for any technical interviews at large tech companies get started using algo expert today by clicking the link in the description and using the code tech with tim for a discount on the platform okay so let's start writing some html to display the posts the first thing i'm going to do here is make a div i'm going to say div id is equal to posts we'll put the for loop inside of the div now outside of the div i'm going to put an h1 tag just to say hey these are all the posts so i'll say a line equals and then center and then post and then slash h1 okay now we will keep the for loop inside of our post div but i'll delete this for now because we're going to display this a little bit nicer what i'm going to do is use a card to display all of my posts a card is kind of like an outline box that has some nice properties from bootstrap so we're going to make a div we're going to end the div the class is going to be equal to card with a dark border so border dark so that will be our card then we want a header for the card and a footer for the card the header which is going to be kind of like a top bar will show the username of the person who posted the post and then we'll have some main text that will be the actual post text then we'll have the date and time that the post was posted at so we're going to make another div here uh this div is going to have a lot of classes on it we're not necessarily utilizing all of them right now you'll see in a second why we need them so i'm going to say card hyphen header this is going to be d hyphen flex this is going to be justify hyphen content hyphen and between and then this is going to be align oops hyphen items hyphen center so again i'll discuss why we need this in one minute for right now you can actually just leave it as card header but i'm just adding these classes here so i don't forget to add them later on this is because we're going to show like a like button and there's going to be a comment button and a delete button and stuff and so this kind of aligns the buttons nicely but we're not adding all of those right this second okay so that's the header so inside of the header what i want to do is show the author of the post so i'm just looking at my kind of cheat sheet here to see how i'm going to show that i believe i'm going to do this with an a tag so a link i'm going to say a ahref is going to be equal to and this is going to be slash and then user slash and then inside of the variable here i'm going to put the user name so i'm going to say post dot user dot user name so when you click on the user's name it will redirect you to the page user slash their name where you can view all of their posts so yeah i guess we can do actually we can say posts that makes a bit more sense and then i'll end the a tag and i will put inside of here post dot user dot user name okay so before we go any further let's just refresh the page here and see what this looks like so if i refresh notice now i get a card and it's showing me the username when i click on this it brings me to a page we haven't yet created yet but that's good it's working so it's showing tip nice so now what we want to do is actually have some content inside of our card so i'm going to make a new class here this class is going to be called card body so div class is equal to card hyphen body i think that's all we need here nice i'll end the div and then inside of here we're going to have another div this class will be equal to card hyphen text and then here we're just going to put the post dot text okay so let's end the div oops let's save and let's see what this is looking like now so let's refresh notice now we get hello my name is tim so nice we have the author we have the text of the post and finally i want the date and time this post was posted at so the way i'm going to do that i'm going to add another div i'm going to say class is equal to and let me go find this right here uh this is going to be card hyphen footer and then text hyphen muted and inside of here we are going to put a date so we're going to say post dot date like that uh and this is actually sorry date created okay so let's refresh this and now notice we get the date and time that this post was created act perfect so hello my name is tim this is by tim and we have our date and time so now we can actually see all of the posts now the last thing i want to add here is the ability to delete a post so how do we delete a post or who should be able to delete a post well only the person who created the post should be able to delete it so what i'm going to do is put in kind of an if statement and a little button that allows you to actually press a delete button only if you are the author of the post so we're going to create this delete button on the card header and the point of this is that the delete button will be on the far right hand side and you can kind of press on it it will show you a little drop down menu that drop down menu will say delete you can press delete and then it will actually delete the post it will implement that functionality in a second so let's go inside of the card header and let's add a div this class will be called button hyphen group it may be btn group yeah it is btn group so btn group let's now end the div and inside of here we're going to put kind of like a drop down button so we're going to say button and this is going to be class or sorry type is equal to button class is equal to btn btn hyphen sm which stands for small button and we're going to say btn hyphen primary because we want this nice blue color and this is going to be drop down and hyphen toggle like that okay we're going to end the button like that and what we're going to do is add one more thing here which is going to say data hyphen bs hyphen toggle is equal to and this is going to be equal to a drop down okay so this is just saying what are we going to toggle when we press this button well it's going to be the kind of drop down menu that we create called drop down okay so now underneath here we're going to say ul we're going to start a list this list will be for all of the buttons in our drop down menu we're going to say li we're going to end the li this is going to say delete and the ul is going to have the class equal to drop down hyphen menu okay we're then going to put a link inside of our li our list item so href is going to be equal to something we'll define that in a min minute and then we will end the a tag now this is going to have a class which is equal to drop down item so drop down hyphen item and for now i think i'm going to leave it at that okay so let's just do a quick summary of what i did here because i just wrote a lot we have a div the class is equal to a button group that's because we're going to have multiple buttons in the drop down menu well in this case we only have one but we could add more we have a button this button is type button class btn btn small btn primary and we are toggling the drop down toggle or the classes drop down toggle so it's going to toggle drop down to come down we have data bs toggle is equal to drop down and then we have a class drop down menu we have a list item which is delete and then we end the list of all of our drop-down buttons okay so when we press on uh this button right here it should toggle these to come down okay so let's just try this quickly let's refresh notice our button is on the right hand side of the screen and when i press this it toggles delete to come down awesome that is exactly what we want now when we press delete right now it doesn't do anything but i will make it so it goes to a page that deletes the post nice okay and the reason why again we wanted all of this stuff is so that delete button went to the far right hand side of all of our uh what do you call its posts okay so now what we're going to do inside of here is make this go to delete hyphen post slash and then this is going to be the id of the post that we want to delete so post dot id nice now we're almost done the last thing i need to do is make it so we only showed this button if the user is actually the owner of this post so only if the user that's logged in wrote the post that we're seeing are we going to allow them to to delete it sorry no other user can delete this post so we're going to do an if statement percent percent if user dot id is equal to post dot and in this case we can just say author because that stores the id of the user who created this post so if that's the case then we'll show all of this so we can just end the if down here so we'll say percent percent and if all right so if i refresh this it should still work we should still see the delete button because we are the author of this post but now if i log out and let's create a new account so let's go sign up and let's go tim2 gmail.com tim2 make a password okay sign up now notice it's not showing me the delete button because well this isn't my post so let's make a post create hyphen post let's say hello test post and put and see now that i can actually press the delete button on the post that i created all right we're getting close to done here a few more touches we need to add obviously we don't want these posts smooshed together so what i'm going to do is add a break line at the end of my for loop so that there is kind of a space between all of my posts so let's go here and let's add a br and now if i refresh you should see that there's a bit of a space so i just added a br right before the end of the for loop so after all the cards that i create we're gonna have that break line nice so now what we need to do is make it so we can actually delete the post so when i press on this button it should redirect us to a page called delete post that's going to take the id of the post that we want to delete we should then delete that refresh the page and well be good to go all right so let's do that let's go to views.pi and let's make a view that can delete our post we're going to say add views dot root we're going to say slash delete hyphen post slash and then i'm going to show you how we can add a variable to our path here so you add angle brackets like this and then you put the name of the variable that you want to kind of grab when someone goes to this group so this is called a dynamic path or a dynamic route so if i say delete post and then i say id what i can do now is say define delete underscore post i can put my id inside of here and whatever the user types in for the id of the post will be passed to this function as the parameter id so this says you can go to delete post and then after that you're going to have some parameter this can be whatever value and that's going to be called id then inside of here we'll grab the id we'll check this is the valid id for a post we'll make sure the person trying to delete this post is the correct person and then of course we'll delete that post or is the authorized person sorry okay so we're going to make this login required as well and what we're going to do here is we are going to actually yeah we can leave this as a get request we're going to start by checking if there is a post that has this id so we're going to say post is equal to post with a capital dot query dot filter underscore by we're going to say id is equal to id so again we're just checking if there's some post that has this id that we would have passed through this parameter if there is not so actually we need to add a dot first here to get the first result so we're going to say if not post then flash post does not exist okay and the category is going to be equal to error okay so we're going to flash that then we're going to return a redirect for the url underscore 4 and this is going to be views.home because we're actually going to kind of go to this page try to delete the post and then just automatically redirect them back home and in fact i'm realizing we can actually just put this here because no matter what happens we're always going to redirect them back to the home page all right so we're going to flash that now else we're going to check if the current user is the owner of this post we're going to say alif the current underscore user dot id is equal to the sorry post dot id so if this is the case we can delete the post but we can actually make this a not equal to okay so now we will flash a message and we will say you do not have permission to delete this post okay and then finally else so if the post does exist and we have the right to delete the post then we will delete it so to do that we're going to say db dot session dot delete post and then db dot session dot commit and then we're going to flash the message post deleted with the category equal to success all right so i think that is all good so that should actually work for our delete post method so we have delete post we take an id we check if this post exists we get the first result if that post does exist we then check okay is the post here do we have a post if we don't have a post the post doesn't exist we flash this otherwise we check if the current user so the logged in user actually did create this post if they didn't then you don't have permission to delete this post otherwise we actually delete the post and then flash yes you deleted the post and i'll just add a period right there okay so let's try this i'm going to rerun the app i'm going to go here and refresh now i'm already signed in as tim2 so i'm going to try to delete this when i press delete we get post deleted awesome and there we go now let's just see what happens if i go to delete hyphen post slash one if i do that you do not have permission to delete this post now i'm noticing that it doesn't seem to be showing me this in red so let's quickly fix that so we make sure the error message shows up as an error message and we can do that by going to base.html okay so if i go to base.html and i find my message flashing which is this mess right here we will check okay so if the category is equal to error then we are showing this otherwise we are showing this okay so this should be working because the category should be equal to error i'm interested in why we're not getting this because if category is equal to error we should show the alert danger otherwise we should show this okay so give me a second i'll be right back okay so it turns out that was quite a silly mistake i'm sure you guys probably noticed that when i was doing this but i forgot to add this category equals error to this flashed message right here so when it was showing this message it wasn't showing it in red but now it is showing it in red you can see if i go here and i try to delete post one you do not have permission to delete this post shows up in red alright so that was my mistake now let's continue so deleting the post works adding the post works the last thing i want to do here is make it so we have a little button that says create post it brings you to the create post page so that you don't have to go to manually slash create post so let's do that i'm going to go to home.html i'm going to go underneath the for loop here i'm going to make a div class sorry not class align is equal to center okay we're going to end the div we're going to put a button here so we're going to say button type equals button class equals btn btn hyphen primary and then i'm going to go with button large i'm going to go slash and this is button and i'm going to make this same create a post now this should redirect us so i actually forget if i need to put an a tag around this or not let me go look at my cheat sheet okay yes i'm going to put an a tag around this that goes to the page that we want so i'm going to say a href equals and this is going to be slash and create hyphen post and i will end my a tag after the button nice okay so now i have this so we're going to go to create post and we have the button and we should be all good okay so let's refresh and now we have this create a post button when i press that it brings me to this page now the last thing i want to do is make a back button on this page so i can go back to the home page without having to manually go here and press home so let's do that let's go to create post let's simply add another button that goes after this form so we'll add a break line here so br okay and then this button will be type button this class will be button button large button primary sure and then we can make this say back okay and then lastly we're going to add an a tag we're going to say a href equals slash home and then this will be slash a like that okay so we now made our button let's refresh and if i go to create a post i now have a back button when i press back i go back to the other page i'm thinking it might make sense to actually change the color of this button so i'm going to do that and rather than making it primary i'm going to make it the default color which is kind of like a gray so if i refresh now oops is default not one hmm let's make this secondary rather than default let's make it secondary and let's see what we get okay that's what i wanted secondary gives us kind of that gray button so now we can go back and we could change the size of those buttons if we want but i think for now that is fine all right so now we are going to end off the tutorial by making it so when we press on a user's name it brings us to kind of their profile where it shows all of their posts so to do that we're going to start by creating a view so our view here is going to be at views dot root so at views dot root this is going to be slash post slash and then we're going to say user name like that we're then going to make this login required we're going to say define and this is going to be posts i guess and this will take a username and then what we're going to do is just query all of our posts so i'll copy this right here but instead of querying it by an id we're going to query it by a username so we're going to say username is equal to username and rather than getting the first result we're going to get all of the results so we're going to filter by the username that we typed in here grab all of the results and then we're just going to pass that to actually we could pass it to the home template but i'm going to pass it to a different template just so that we can make this a bit more unique so once we get all the posts by a certain user then what we can do is say return and this will be render template and this template will be post dot html we'll pass the user equal to current user and we'll pass the posts equal to post like that this should be a plur okay so that's fine now the next thing that i'm going to do here is just a quick check to make sure that the username the person typed in actually does exist so the way i'm going to do that is say user is equal to user dot query dot filter underscore by i'm gonna go username is equal to username and then get the first result the reason i'm doing this is because i don't really want to show a page if the user that this person typed in doesn't actually exist so let's make sure the username does exist if it does exist we can do this we can show all of their posts otherwise we can just flash a message and say hey no user with this name right so i need to import user so let's go to models and import user and let's just make sure the user exists we're going to say if not user then we're going to flash a message we're going to say no user with that username exists okay the category is going to be equal to error and then we're going to return a redirect for the url underscore four we'll move this in in a second views dot home okay so let's grab this let's put this here and then otherwise we can do this and we can show all of their posts nice so now what i'm going to do is go to the post.html page all right so we're now on post.html now what i want to do is i want to have the title of this page be like user names posts right and then i want to have a header that says post by whatever this person's username is so what i'm going to do here is go to views.pi and i'm just going to pass one more thing i'm going to say username is equal to username just so i can access this right here the variable that's a part of the url so now if i go to post.html i can make the title be user name and then apostrophe s post right so that'll be the title of this page and in the same way i'll copy this and i'll use this for kind of the header that will display on the page so inside of the content block what i'm going to do is say h1 slash h1 we'll say align is equal to center and then same thing we'll put this right here okay so now that i have this i want to display all of the posts right and the way i'm going to display the post is going to be the exact same as what i've already done on this home page so rather than me writing all of this code again what i'm going to do is take all of this code and put it into a template and i'm going to inherit from that template on both the home page and the post page so i'll show you how this works but we're going to copy all of this code here that's inside of what is it home.html so we're going to copy all of that and we're going to go inside of post div and inside of the content block we're going to paste it okay so now we have all of the code that we have from the home page now i'm just going to start kind of reconfiguring a few things here so i'm going to take this div which is right here so this div corresponds with this div tag i'm just going to move it up so that it ends at the for loop so notice now when i save this we have a separate div here and then we have this div right here now what i'm going to do is i'm going to start creating some blocks inside of this template so i have this header right and this header is going to be different based on the page that i'm displaying the post on on the home page i want to say posts but on the post page i want to say the user names posts right so the way i'll do this is i'll say block and then oops this needs to be done differently percent percent i'm going to say block header like that and i'm going to end the block here so i'm going to say percent percent and block now i could actually just put this right inside where the text is so i can end the block there and start the block here so this way all we have to do is just type in the text we don't need to rewrite the h1 tag perfect so that is my block for the header now this is all going to be the same right this entire div is going to be the exact same for all of my pages however this button here at the bottom may not be so what i'm going to do is just put this inside of its own block as well i'm going to say block and i'll just say button or i can say maybe footer because it's the end of the page and then i can say percent percent and end block so there we go so what i've done now is i've created this template this template extends base.html and now i'm going to go to home.html and i'm going to extend from the postdiv.html so post underscore div and this is a plural i believe nice now i actually don't need to change anything here i can override the block title like i have done before and this should just show me the correct page because i'm just inheriting this post div template here which has all of the stuff that i had before on the home page now though i'm going to go to post.html and rather than inheriting from base.html i'm going to inherit from post underscore div dot html now i can change the title like this that's fine and for the block content i'm going to get rid of this okay and rather than actually i'll leave this here but rather than it being block content i'm going to make this block header and then all i'll do is just put user names posts like that inside of the header block and i think for now that's actually all i need to do now i may want to remove the button for creating a post so the way i can do that is i can just override the block and put nothing there so i can say block footer and i can say percent percent and block so let's just rerun this and see if this is working at all but you can see why this is advantageous because now if i ever change how the posts are displayed i only need to change them in one place and both my post page and my home page will update based on the changes made to this template right here so let's go and refresh this and okay we're getting some type of error i guess it's just not showing the correct post so let's try to go to posts slash tim and see if that does anything no okay that's not working so let me just have a quick look here and see what's wrong okay so i found the error if you go to the home page here notice how i was writing block content and end block since i was doing that i was overriding the content block from mypostdiv.html so if you just remove that and you press save so now you just have the title and you go here and you refresh notice how it actually shows you the proper post however when i click on this here i get some error it's saying website.model.post has no property username the reason i'm getting that is because i've made a mistake inside of myviews.com so if you go here notice i have where is it here post username equals username that's not going to work i clearly cannot query the post by the username what i need to do instead is query the post by the author so i'm going to say author is equal to and this is going to be user.id so i've now got the user right so i have the id of the user this is storing the id of the user who owns the post and so i'm going to query all of the posts by the id right by the author so i just need to change that and now this should actually work properly so if i go back to post and i refresh notice i get tim's posts there we go perfect the last thing i want to do here is i want to make it so that we have a little back button that brings us back to the home page so that's pretty easy to do i'm going to go to post.html notice how we already have the block footer so inside of the footer block i'm just going to go to the post div i'm going to copy this div right here and i'm just going to put a button that goes somewhere else so rather than create a post i'm going to say back and this is just going to go back to slash home there we go so now i have that button here same as what we've done before and if we refresh we have the back button and i can go back and it brings me to the posts page perfect so with that i think i'm going to end the video here a reminder that all this code will be available on github if you guys enjoyed the video please make sure to leave a like subscribe to the channel and i will see you in another one
Original Description
Welcome back to another video in this blog tutorial series! In this video, I will be showing how we can create posts and have those posts show up on the home page. I'll also show how you can view all posts posted by a single user.
💻 AlgoExpert is the coding interview prep platform that I used to ace my Microsoft and Shopify interviews. Check it out and get a discount on the platform using the code "techwithtim" https://algoexpert.io/techwithtim
📄 Resources 📄
Code In This Video: https://github.com/techwithtim/Flask-Blog-Tutorial/tree/main
⭐️ Timestamps ⭐️
00:00 | Overview
00:37 | Dynamic Navbar
04:48 | Database Bug Fixes
06:25 | Create Post HTML
08:39 | Create Post View
11:11 | Post Database Model
12:43 | Foreign Key Relationships
19:00 | Creating a Post
22:27 | Displaying The Posts
29:50 | Delete Post Button
35:41 | Delete Post View
40:56 | Creating Some Buttons
43:29 | Viewing User Posts
◼️◼️◼️◼️◼️◼️◼️◼️◼️◼️◼️◼️◼️◼️
💰 Courses & Merch 💰
💻 The Fundamentals of Programming w/ Python: https://tech-with-tim.teachable.com/p/the-fundamentals-of-programming-with-python
👕 Merchandise: https://teespring.com/stores/tech-with-tim-merch-shop
🔗 Social Medias 🔗
📸 Instagram: https://www.instagram.com/tech_with_tim
📱 Twitter: https://twitter.com/TechWithTimm
⭐ Discord: https://discord.gg/twt
📝 LinkedIn: https://www.linkedin.com/in/tim-ruscica-82631b179/
🌎 Website: https://techwithtim.net
📂 GitHub: https://github.com/techwithtim
🔊 Podcast: https://anchor.fm/tech-with-tim
🎬 My YouTube Gear 🎬
🎥 Main Camera (EOS Canon 90D): https://amzn.to/3cY23y9
🎥 Secondary Camera (Panasonic Lumix G7): https://amzn.to/3fl2iEV
📹 Main Lens (EFS 24mm f/2.8): https://amzn.to/2Yuol5r
🕹 Tripod: https://amzn.to/3hpSprv
🎤 Main Microphone (Rode NT1): https://amzn.to/2HrZxXc
🎤 Secondary Microphone (Synco Wireless Lapel System): https://amzn.to/3e07Swl
🎤 Third Microphone (Rode NTG4+): https://amzn.to/3oi0v8Z
☀️ Lights: https://amzn.to/2ApeiXr
⌨ Keyboard (Daskeyboar
Playlist
Uploads from Tech With Tim · Tech With Tim · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
A* Path Finding Algorithm(Visualization)
Tech With Tim
Python Programming Tutorial #1 - Variables and Data Types
Tech With Tim
Python Programming Tutorial #2 - Basic Operators and Input
Tech With Tim
Python Programming Tutorial #3 - Conditions
Tech With Tim
Python Programming Tutorial #4 - IF/ELIF/ELSE
Tech With Tim
Python Programming Tutorial #5 - Chained Conditionals and Nested Statements
Tech With Tim
Python Programming Tutorial #6 - For Loops
Tech With Tim
Python Programming Tutorial #7 - While Loops
Tech With Tim
Python Programming Tutorial #8 - Lists and Tuples
Tech With Tim
Python Programming Tutorial #9 - Iteration by Item (For Loops Continued...)
Tech With Tim
Python Programming Tutorial #10 - String Methods
Tech With Tim
How to Overclock a NVIDIA GPU
Tech With Tim
Python Programming Tutorial #11 - Slice Operator
Tech With Tim
Python Programming Tutorial #12 - Functions
Tech With Tim
Python Programming Tutorial #13 - How to Read a Text File
Tech With Tim
Python Programming Tutorial #14 - Writing to a Text File
Tech With Tim
Python Programming Tutorial #15 - Using .count() and .find()
Tech With Tim
Python Programming Tutorial #16 - Introduction to Modular Programming
Tech With Tim
Python Programming Tutorial #17 - Optional Parameters
Tech With Tim
Python Programming Tutorial #18 - Try and Except (Python Error Handling)
Tech With Tim
Python Programming Tutorial #19 - Global vs Local Variables
Tech With Tim
Python Programming Tutorial #20 - Classes and Objects
Tech With Tim
Cool VBS Script to Prank Your Friends!
Tech With Tim
How to Overclock an AMD GPU
Tech With Tim
Best GPU'S For Mining Ethereum (2018)
Tech With Tim
Recursion and Memoization Tutorial Python
Tech With Tim
Ethereum Mining Rig - Hardware Guide
Tech With Tim
Pygame Tutorial #1 - Basic Movement and Key Presses
Tech With Tim
How to Install Pygame (Windows 8/10)
Tech With Tim
How to Trade Your Cryptocurrency (Bitcoin, Ethereum etc.) For Cash!
Tech With Tim
How to Mine Ethereum 2018 - WORKING (Super-Easy)
Tech With Tim
Microphone Comparison - $10 Mic vs $150 Mic (Blue Yeti USB)
Tech With Tim
Pygame Tutorial #2 - Jumping and Boundaries
Tech With Tim
Pygame Tutorial #3 - Character Animation & Sprites
Tech With Tim
Pygame Tutorial #4 - Optimization & OOP
Tech With Tim
OBS Studio Tutorial - Best OBS Settings
Tech With Tim
Linear Search Algorithm - Python Example and Code
Tech With Tim
Make Any Mic Sound AMAZING! (WITH OBS)
Tech With Tim
Binary Search Algorithm - Python Example & Code
Tech With Tim
Pygame Tutorial #5 - Projectiles
Tech With Tim
Pygame Game - Mini Golf
Tech With Tim
Pygame Tutorial - Projectile Motion (Part 1)
Tech With Tim
Pygame Tutorial - Projectile Motion (Part 2)
Tech With Tim
Pygame Tutorial #6 - Enemies
Tech With Tim
Pygame Tutorial #7 - Collision and Hit Boxes
Tech With Tim
Pygame Tutorial #8 - Scoring and Health Bars
Tech With Tim
Cloud Mining vs. Hardware Mining - 2018
Tech With Tim
How to Install Pygame on Mac OSX (Fast-Simple)
Tech With Tim
Pygame Tutorial #9 - Sound Effects, Music & More Collision
Tech With Tim
Pygame Tutorial #10 - Finishing Touches & Next Steps
Tech With Tim
How to Fade Your Screen in Pygame [CODE IN DESCRIPTION]
Tech With Tim
How to Create a Button in Pygame [CODE IN DESCRIPTION]
Tech With Tim
Pygame Side-Scroller Tutorial #1 - Scrolling Background/Character Movement
Tech With Tim
Pygame Side-Scroller Tutorial #2 - Random Object Generation
Tech With Tim
Pygame Side-Scroller Tutorial #3 - Collision
Tech With Tim
Pygame Side-Scroller Tutorial #4 - Scoring and End Screen
Tech With Tim
How to Create A Message Box in Python - Tkinter
Tech With Tim
Is Ethereum Mining Still Profitable - Is It Worth It (April 2018)
Tech With Tim
How to Run MAC OSX on a WINDOWS PC (Clover Boot-loader)
Tech With Tim
Programming Problem #1 - Alphabet Soup (Beginner/Novice)
Tech With Tim
More on: Python for Data
View skill →Related Reads
📰
📰
📰
📰
Understanding Algorithm Running Time
Medium · Programming
Common Methods to Find GCD
Medium · Programming
Recursion vs Iteration: Choosing Your Path Like Neo in *The Matrix*
Dev.to · Timevolt
You Don’t Need to Solve 500 LeetCode Problems. You Need to Recognize 12 Patterns.
Medium · Programming
Chapters (13)
| Overview
0:37
| Dynamic Navbar
4:48
| Database Bug Fixes
6:25
| Create Post HTML
8:39
| Create Post View
11:11
| Post Database Model
12:43
| Foreign Key Relationships
19:00
| Creating a Post
22:27
| Displaying The Posts
29:50
| Delete Post Button
35:41
| Delete Post View
40:56
| Creating Some Buttons
43:29
| Viewing User Posts
🎓
Tutor Explanation
DeepCamp AI