Photo Album App With Django & S3 Buckets

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on guys so in this video what we're going to be doing is building out this image gallery using django so this is a simple little application where we're just adding in images here we're storing them we're going to be able to search images by category and then just store these in our database here so the reason why i'm making this course here is i had somebody ask me about uploading images into aws s3 buckets so what we're going to do here is we'll build out this application and then towards the end we're actually going to upload these images into aws s3 buckets so amazon web services so if you're here just to see how to do that where we can just upload to aws i'm going to have time stamps at the end of this video so you can just go ahead and look at that and you can just follow that section instead of building out this entire template because we're gonna start from scratch here or at least almost from scratch i do have a django project already built out and then we're just gonna start adding to it and customizing it so let's go ahead and take a look at the product demo here really quick so the first thing is we just have images and we just have categories here so it's a simple application we can go to any one of these images i can go to uh the category of dennis and solomitha i can go ahead and look at the image we have a description go back here and we can go back to another image and view that so we can filter these by categories so right now by default on the home page i am just opening up all the images but if we go to travel here so we can see the category of travel for these two so if i hit travel here now we only see all the images under the category of travel if i go to dennis and solomita we just see myself and my wife here if i go to food we can see the food here and then if i go to all we can see all images now if i go to add a photo here we can actually add new photos i can always go back so let's go ahead and add a photo here so the first thing is i'm just going to paste in a description so we'll just go to lorem ipsum we'll just get some dummy text here doesn't really matter what it is we'll just take that paste this in here and we can select a category so if i select a category let's say we'll just do dennis and solomita and i can go ahead and choose an image for that so if i go to my photos here and i'll provide you with these photos if you want to use these if you want to use your own go ahead and do that so we'll go into family here so that's actually going to be under dennis and sula amita and let's grab this picture so i like this picture i want to upload it we'll submit that and there we go so we have our picture now if i filter that we can see that here now if i add a photo here without a category so if we don't select a category let's say we want to add in a new category so i don't have to select a category at all the image will just show up there under no categories but if i want to create a new category so let's see let's just do what do i have here so let's go into my photo library i want to see what kind of categories so let's do nature so first let's upload an image here we'll just upload this picture this is from a family trip to destin florida so we'll just do travel here so travels let's submit that and now we created a new category of travel here so oh it looks like i already had that so let me try that one more time so let's go to add and then we'll go into photos uh let's just do nature so that's what i meant to do oh that was supposed to be nature so let's just grab this image now and let's just type in nature so we don't have this as a category yet but if i upload it let's add in the description if i submit this there we go now we have a new category of nature with one image so that's the entire application i'm always going to get requests for people to ask to build in login authentication different things like that if you want to do that what i'm going to do here is i'm going to recommend you just put that in the comment section and i want to ask you if you guys are willing to pay for a udemy version of this so if i do a udemy course on this or on my own platform i would be willing to put out the entire application but i've built in authentication search pagination so many times that it just seems unnecessary to do this in one video but if you feel like you would be willing to pay for the entire application leave me a comment and maybe i'll build this out in a udemy course and then put that up for like 10 so just let me know and then i'll see if there's demand and i'll build it so with that being said let's go ahead and just start building out the product so i can go into my text editor so i built up or i just created a django application all i did was i did django dash admin start project so django dash admin and then start project so i just did that and i called this one photo share so go ahead and create it create your virtual environment if you want to use one i already have it and i added it into my application so if we go in here we just see manage.py all the default stuff so i'm assuming you already know a little bit of django so go ahead get things set up build out your application and now i just want to start from building out our app so we have our project that's the only command we've ran and i want to go ahead and create our app so inside of photoshare so that's my application name or my project name i want to create my first app and i'm just going to call this one photos so that's going to be my app we're only going to have one so let's just do python manage dot py star app and we'll just call that photos so we'll create it we'll connect it really quick so now we have our app here with our models of views and let's go ahead and create that so we want to connect that to my app stop py file so we want to connect that to photo config here so i just want to make sure my django project knows about this so we'll go into settings.py let's just do this so we'll just do photos so we're going into photos dot apps so into the app stop py file and we're going into photo config so that's inside of our installed app and i'm using vs code so i'm just going to go ahead and set that by default so now that we have our app let's go ahead and create our url routing system so we want to create our urls our views and our templates so we'll go into photo or photos not photo share and in here let's go ahead and create our templates first so in our templates i'm going to store those in my app here so we just need to create a folder called templates and inside of templates i want to create another folder called photos so whatever you called your app i called mine photos let's go ahead and create that so that's how django requires you to do it if you're storing your templates in your app so now inside of photos i want to create a few templates so we'll go into photos new and this is going to be a file so we're just going to call this one gallery.html so let's just add that in i want to add in some text here so we'll just do h3 and i'm just going to say gallery so i have a couple of shortcuts here so if i change my tags here let's say i change that to a div the closing tag autocompletes and if i save it and my formatting is off it's going to auto complete that too so let's say my h3 tag is here and it's indented all the way to the right so if i save it it's going to auto fill so you'll notice that my indentation is going to fix every time i save it so that's our first template the next one is going to be add.html so you want to you can call that whatever you want but this is for our form when we create a page here so or create a new image so when we go to add photo this is that page so let's see we'll go into add.html i'm not going to add anything in here yet let's close let's just close this out so just minimize that and the next template is going to be my photo so photo dot html so when we go to view a photo and this is just a demo so we will start from scratch so when we go to view a photo we want to see it so that's the demo here and that's in photo.html so we have our three templates we have our gallery which is the home page the photo page and the ad for the form so let's go ahead and create the views now so we'll go into our views and we just want to render out these templates so we'll just create a function based view and i'm just going to call the first one gallery so that's gallery we're going to take in request then we'll just return the template so we'll do return and that's going to be render we need to pass in request here so throw in request and let's see we'll just do photos that's the app name so photos and then forward slash gallery dot html okay so now all i have to do is just copy and paste this i'm going to repeat this three more times and we'll customize the values so this next one's going to be for my photo so we'll just do view photo and that's going to go to photo.html and then we also want on me to put an o there so then we just want to do add photo okay so this one's going to be add html so now i just want to configure my urls here so what i'm going to do is create my urls file here and then we need to connect it in our root urls.py file so we're going to call this urls.py and in here we first need to import our path our path function so we'll just do from django dot urls import path and let's go ahead and also import our view so we'll just do from dot views or from dot import view so we're just going back one file and we're actually in the same file structure so we're just going to import that so we can import all the views and then we need to set our url patterns so url patterns set that right there and let's create the paths here so we'll just do path our home page is going to be our gallery so we'll just do views dot gallery and then i'll just give this a name so we'll just name that gallery here and then we also need to add in a comma here i'm going to copy and paste this two more time and then or two more times and we need to add one for the photo so we'll go into the photo and we're going to get a photo by its id so we can use a slug field an integer or just a string value so i'm just going to use a string and i'm going to call that pk so that's how we need to get that in the view so if i go back to the view for my view photo we're going to pass in that primary key so i call that pk right here so we're just going to get that right here and let's go ahead and copy and paste the view name so just change that to views dot view photo and this is going to be photo for the name can't spell photo for some reason so this next one this is going to be for adding an image so we'll just do add here and that's going to be add photo and we'll just do add for the name okay so we have our views we have our or we have our urls and our views but we need to go back into i just realized i have a comma right there that needs to be outside and so do these right here so let me just fix that so we have our view and our views and our urls here and i just need to go back into my base application and connect those right here so let's go ahead and add in the include method here so this is inside of my django project so not in the app so we can see photoshare urls.py and then we have the new one that we created that's our urls.py so we just need to point to this urls.py file and let that take care of everything so we imported include here so now all i have to do is just set that base url so we're going to leave that as an empty string and we're just pointing to include and then we're going into photos dot urls so we're going into the photos app we're going in here and going into the url so let's add in that comma now when we send it to this file this file right here is going to take care of that url routing so let's start up our server and see what we have so let's just make sure that was taken care of and we'll move on to the next section so we can do run server we don't have a database yet we'll take care of that in a minute so i'm going to close out the demo and i'm going to open up poor 8000 so i just have that shortcut here so we can see gallery that's our home page if i go to let's see we'll just do photo and then the id of three so view photo got an unexpected argument let's see what did i do here so we'll go into photos urls here so we have our string and our primary key so if i save that i just need to save the views in the url file and i think that should do it so there we go we have nothing in there but it's working and if i just do add that's also a path so those are all complete now so let's go back into our template and start building out the template itself so for this we are going to use bootstrap here so i don't want to focus too much on styling so let's go ahead and we'll add that in here so in this template now we're just going to start by doing html and this should give me my boilerplate files here so let's see i don't know why that's not auto-completing so let's just try h t ml here okay so there we go we got our base files here and in here what i'm going to do is just call this gallery so this is the page here we'll add that in we have our meta tags here and if it didn't auto complete just go ahead and write this out we just have our basic html tag our head tag body and the closing html tag so let's go into bootstrap so just google up bootstrap here so boot strap and we're gonna use bootstrap five here but it doesn't really matter if you're using bootstrap 4 they should still be the same so let's go ahead and go to bootstrap let's grab this css cdn link right here so that's the css we're not needing the javascript we want to add that to our page so we have the styling and we have access to all the bootstrap classes and ids and after that let's go ahead and start building out our template so if we go to bootstrap here we want to build out our layout so we'll just start with that so we can go to bootstrap and then we'll go to layout we'll just google that up and it's going to give us the grid system so we'll go into our layout and we just want to build out our container our rows and our columns so if you're not familiar with bootstrap this shouldn't be over complicated you can take a look at the documentation but i'm gonna go pretty slow so it should be easy to follow so all we did was add in this link now we have access to all the bootstrap classes so when we add in these classes it's gonna give us the styling boost trap gives us so in here let's go ahead and go into our body and the first thing i want to do is add in our container so we'll create a div here and inside of a or for this first day we'll just call this container and we'll just leave it like that so that's the only thing we need there and then for our or inside of our container we want to create a rows so we're going to have two columns we'll have that left column and the right column for the images so we'll create our row and that's supposed to be a div sorry about that so we'll create the div here and the div is going to be called row so we'll just give that a class of row and let's go ahead and create our columns now so we'll create another div here and this div is going to have the class of call dash md so for medium there and we want to give it the width of our three columns so we want it to be smaller we have a 12 column grid system so this is going to take up three columns of that grid so we have three right there and we will create another column here and i'm gonna call this or i'm just gonna give this the size of nine so that is supposed to total to nine so we just have our nav right here and we have our gallery so i'll just add that in so we can see it so gallery and if i save this now we can go back to our page we'll go to the home page okay so if we go here now we see that left column and the right column so let's start building out this navigation right here so for this i'm just going to go to bootstrap here and i'm just going to keep googling things up instead of navigating actually let's see i can go to contents or components and we just want to go to card okay so never mind i can get that here so what i'm going to do is i'm going to use a few of these so we're actually going to end up using a card like that but if i can go in here in this so right here so inside of our cards here i want to take this one so i just want to say gallery right here and then these will just be linked so i can just grab this code right here and we'll just customize this so let's go back into our text editor and in here inside of that navigation let's go ahead and paste that code so i'll create that separation so right here we have our column that opens and closes right here and we just pasted that code in right here so we have our width which i just want to remove that the card should already provide that and for the title i just want to say gallery so if i save this now we should be able to see that right here so if i refresh that there we go so let's actually add in some styling so we can't see this and that should be called not gallery but categories so categories okay so we have that and i'm going to go to my body and i'm just gonna give it a class here and that's gonna be m dash we'll just do five so that stands for margin and we're just giving it the amount of five right now so if i refresh that there we go so let's go ahead and look that up really quick so bootstrap spacing i just want to make sure you understand what's going on here so these classes right here if we add in m or p so p is for padding m is for margin then we can do margin top with m dash t and y is going to be margin top and bottom and then the amount of padding or margins so that's what we just did there so let's go ahead and go back here and let's continue here so for the categories i'm just going to leave these and i want to leave these ones right here but i do want to add in an all link right here so that's to view all of them just like we saw in that demo so if i go in here i'm just going to take one of these here we'll copy and paste that and we'll just say all so i'll set that to all and then we're just going to output these ones dynamically so let's go ahead and output our gallery here so for our gallery let's see how do i want to do this so i'll just wrap everything inside of a big card here so we'll just create another div here actually i don't want to do a card i just want to output it in a row so we'll just do div here and we'll close this off so we'll just do class and we'll call that row i need to take out that extra angle bracket right there so we have our row and inside of the row we're just going to dynamically output all of our photos so these are going to be wrapped inside of a card so we're just going to go ahead and create another div here and i can probably just go ahead and actually pull that from bootstrap so let's go ahead and get that so i want to take this card right here i like the style so i can have my image right here and then just the description the link to the page or whatever we want to add so let's go ahead and just copy this so pay attention to the urls or where i'm at here so just copy this and let's go ahead and paste that in here if you want to write it out go ahead and do that i just want to remove the width right here and let's see so for the images let's go ahead and add in our own images so we'll just say cat photos so cat pictures and we'll just take in let's see i'm not a cat person it's just kind of funny to use these it seems like everyone does this so let's go ahead and find a bigger image here so just take this one right here open up the image copy that url and let's paste that in for the source so if i save that now we should have a cat photo here so if i remove that right there let's go ahead and take a look at that so we have our card and our photo of the cat so i want to make sure this doesn't take up the full screen so let's go back in here and i'm just going to give this a class for the image so let's go into the image and i just want to add in a class and i'm going to call this one image thumbnail so let's see i can just take that out right here and we'll just say image dash thumbnail and i'll put in the css right here so let's just take that go up here and let's see so i'll just paste that or i'll add this inside of head right here and we'll just add in a style tag so just style this right inside here we won't create our own style sheet and let's see so for image thumbnail i just want to make sure it doesn't overflow so i just want to give it a max height here so we'll just set that to 200 pixels let's save that so that should move it down and for some reason it's still overflowing so let's go back in here and i just want to wrap this inside of a column because we're just outputting the cards here but i want to make sure that we're wrapping that in a column so let's go ahead and create a div around this so i'll just copy this right here and i'm going to remove it we'll create the new div and for the styling here i'm just going to give that a class of call so a column dash md and we just want to make sure it has the width of four so i think that's what's causing the overflow so if i save that there we go so that looks a little bit better so now i just want to add in a button right here so we want to add in the category and the button so in here let's go ahead and add that in so we'll just add in the button underneath our card body so still inside of our card body i can remove the text here and let's just say category so just do category and we'll just set this to pet right here or pets and then underneath our category let's go ahead and add in a link so that's going to be outside of our card body so we'll just go ahead and add in a a tag right here and we'll just say view so we want to view the photo and we want to style this too so we'll just give this a class of button here so this is going to be btn btn-outline so bootstrap gives us a bunch of styling here we'll just set that to outline we want to make sure it's a dark button so we'll give it the class of btn dark and i also want to make sure the button is small so we'll do btn-sm and we'll just add in some margins so m one so that should give us a button here let's take a look at that it doesn't link anywhere so let's go ahead and create that link well actually we'll create that link in a second once we actually make that page hey guys so sorry for interrupting the video but i left out one part here so i noticed this at the end and we need to add in some spacing here so before you continue go ahead and just add in my two for the class right here in our card so this is in gallery.html i'm just going to take this clip put it in so you can continue with the video so if i save this and if i refresh it we should see that spacing here so make sure you add that don't forget about this so let's go ahead and add in a couple of these so i just want to go ahead and copy and paste this see how it looks here and then eventually that'll be dynamic so for the category i want to change this to small so make sure you actually replace the closing tag here mine autocomplete so i just want to save that and let's go ahead and take this column right here so again with django this will be dynamic so let's go ahead and just copy and paste that and then we'll change this so if i refresh it we should have multiple images so let's see that looks like my server was off so if i just go ahead and go back here there we go so we have our images here and now let's go ahead and create the photo page so for the photo page when i click on this uh we want to link this to our photo page here so we just need to add in an ahref so we'll do href and we'll use our dynamic urls here so inside of our url we'll just do url like that and the name of our url path so let's see that was photo so we just want to use that name right there so we'll just do photo so photo like that and we need to pass in the photo id so for now we'll just pass that in manually like that so we'll just pass in the idea five so all of these will take me to that link so if i click on this let's see so let's refresh that click on the link oh that was to the first one or the last one actually so now we're taken to that page so photo with the id of five so let's go ahead and update all of those really quick it doesn't really matter but i just want to make sure that all the links work so that's to the a tag i'll add that in right here and that should be good or at least to most of them so the first one is the one that i really care about so that takes me to that page and let's go ahead and start styling this page so for the photo page i want to go ahead and create my boilerplate files again or my boilerplate html so go to photo.html and let's start typing that out for some reason it's not auto completing so let's try that again html samples so i'll just get rid of main.js in my style sheet there so we don't need it and for the title i'll just say photo so we have that we have our template here and let's go ahead and create our container so i want to make sure for the body to add in that same margin so we'll just add in class with a margin of five and inside of the body i just want to create my container again so we'll create the container and we'll just give this a class of container okay so we have that and we want to create our row so we'll just do another div here let's see let's go back here so div and this is going to have the class of row so we just want to make sure that all the content inside is centered so we can just do justify dash content so justify dash content dash center so that's just going to center my content there and in here i just want to put everything inside of a column so just give it the classic call so class that's going to be call here and we'll just let that be full with so that's good here and the first thing i want to do is create a back button so i want to go back to my home page when we need to so when we go to a viewer page or view a photo we want to make sure we can automatically go back so we'll just do go back here and let's add in the styling and the link so for the styling we'll just do vtn and then i can just do btn-darks i want to make sure that's a dark button and i want to set some margin to the top and bottom so we can do my three so let's create the link itself so we'll just do href here and this is going back to my gallery so i called that gallery so we can do url and then gallery so when i'm doing this for anybody that's newer to django i have to put that in double quotes and then this in a single quote otherwise i'm gonna have some issues or you can do single quote and double quote but it just has to be a little bit different so let's go in here we'll go into photo so we can see go back but for some reason it's not styled so btn btn dark and then my why is that not working so it's odd oh i forgot to add in bootstrap here so i need to add in the bootstrap cdn so normally you can just create a template here i'm not trying to go into that part of things so we'll just add in our bootstrap cdn into myphoto.html and that should do it so now we have our container and our back button so let's go ahead and output the actual image so in here we'll just still inside of our column i just want to add the image so we'll create another div here so we'll wrap that in a div and i just want to make sure to add some styling here so i'll just add this in line so we'll just do style and i'll just do height here and i'm going to set that to 90 viewports that's going to take up 90 of the screen and that's for making our image full height here or at least full height so i want the image to inherit from the parent so inside of that div so we have the id where we have the link to go back to the page then we have a div here and in here we're just going to create an image tag so we'll just do image or image right here close this off and we'll just set source here and for the source let's just use this same image from our cat picture so we're just going to continue using this for now so we'll take that paste that in here and let's see so down here i also want a description so let's go ahead and add that underneath here so we'll just create a paragraph tag and that's still inside of the div so i want to keep that in here so let's see so that's going to be right here in a paragraph tag and we'll just use one of these descriptions so we'll go back here actually we're just going to use lorem ipsum so i'll just copy that right there and let's paste that in here okay so let's view the page right now see what we have so far okay so we have our picture and it takes up way too much of the screen so the picture is really big here so i want to make sure to fix that so let's go in here and let's add in some styling for the actual image so i'm going to put in some inline styling so we're still in the image tag it's just indented right here so if i move that right here we can see that that's next to it so inside of this styling let's just do max width here and i want to set that to 100 so i don't want it to always be 100 but i want it to at least max out there if it is that big and then we want to set a max height so i don't want to force it to be tall but i just want to give it the option and that's going to be 100 of that div right here so 100 of this viewport so if i save this let's go ahead and take a look at what we have so we have that cap picture everything looks good so far if we add a picture that doesn't really fit inside of one of these i also want to fix the styling here so let's go back into our gallery here and let's see so let's take in another cat picture so we'll just do cat pics and i want to find a picture that is a different size here so we'll just take in this one right here let's take in that image we'll just do open image a new tag or a new tab so let's take one of these and we'll just paste that inside of gallery.html so let's just replace one of these cat pictures so let's just replace the first one change that right here save it and let's see so you notice how the image is distorted we want to fix that so this is a simple fix if we go into our text editor so if we go back here what i want to do is just create some styling for it so i just want to give it a class here or we actually have the class for our image thumbnail so for this all we can do is just do object fit and we'll just do cover so that just means it's going to cover it but it's not going to it'll just crop the image where it needs to but it's still going to show it so we can see that cropped it might not be the best for a thumbnail but it's just a thumbnail so it's not like it's the final picture so if we go in here and view it we're only going back to that original cat picture because that's all that was in there but the image would show up in in its full size so we'll create the add to or add a new photo page here in a second we want to go ahead and build out our database and configure our static files so we're not having to use these images from the internet so before we do that i just want to add in a button here so let's go ahead and build that out so underneath here let's go ahead and find these links right here so let's just do that let's see i want to do that inside of this ul tag so we'll just create the link right here so we'll just add in another li so let's copy one of these paste that right here i want to remove the content inside and we're just going to create an a tag so just create that and let's just call that add photo so this will take us to the add page so before we style it let's create the link right here and we'll just set that url here so we'll do url and that's going to be to add so that's what i called it inside of my urls.py file so that's add we're pointing to that page here and let's add in the styling so for the styling let's just do btn so button here btn-outline so i want to make sure it's an outline button and that that's going to be btn dash small so btn-sm and something looks off here btn outline i guess that's good i don't know why it's doing that so we have that i want to add in some margin so we'll do m1 and let's save it and see what we have here so if i refresh that it's still not giving us the styling here so let's see oh and that needs to be btn dark here so we're not going to outline it we're just we'll just say dark so btn dark and then btn small so let's go back here still not showing up let's see oh i see that was supposed to be a class that was i don't know why i did styling so i thought i was going to inline that so there we go so we have our button and let's see do i want to make that full width i can just do btn block here so let's just do btn dash block i think and then dark i think that's how to do that okay let's go to bootstrap really quick so i just want to look that up so we'll do uh go to bootstrap we can go to buttons here okay so buttons and how do i make that full width so that's vtn and then we just do btn block so all i had to do was change that back to dark right here and i just remove class and that's going to be btn dash block okay sorry about that so let's go back in here let's check that out okay so i think it's actually the list item that's not allowing me to do it because i keep looking at it and everything looks fine so maybe that's the issue so let's try that okay so there we go so that was a little bit annoying but now we have it and this page links us to the ad page which we don't have yet we'll build that out in a second and we have our view page with our back button so let's go ahead and build out our database now so we'll go into our models file so we'll build this out then we'll migrate it so we'll go into photos here so that's our app name inside of models.py so in here we're going to create two models so the first one is going to be a category so category and this is going to take or in here from models dot model so the model is going to be capital m right there let's go ahead and create that and the only thing we need here is the name so we'll just say models dot char field so character field will set the max length so we need this for character field uh let's just do 100 here so that's the max length and let's see i think i can just do null we'll set that to false so we don't want to allow this to be blank right here and blank is going to be also false so we just want to make sure that when we're saving it that we always have a name in the form so now with that being said let's return the string here so do underscore string and then we'll pass in self okay so for the return value this is just going to be self dot name so we're just returning the name and we also want a photo model so this is going to be the actual photo and how we're going to store it so we'll just change this to photo and let's see so for the photo model there's a few attributes here so the first thing is i want to have a parent-child relationship to my category so we'll leave this right here so for the name we'll just change this to description it's a description and we just want to set that to let's just do 500. so somebody wants to leave a longer description that's fine we don't want to we want to make sure that that's not blank so we'll leave that there and i want to set that relationship so we'll just do category and let's just change that right there and this is going to be models dot foreign key we want to set the relationship to a category so paste that in and then on delete so on delete we just want to set this to nulls so there's cascade so that means if the category is deleted uh if we do cascade that means all the photos that are related to that will be deleted but we don't want to do that we want to delete a category and still be okay with that photo staying so we'll just do undelete and this is going to be models dot set null so that means we're going to set the value of category in this photo to null but we don't want to remove it so we have that and for the image we're going to have to do something a little bit different here so we're still going to need to configure our static files with this image to upload it in the right area but for this we're just going to do models dot image field and let's see we want to make sure we always have an image so null is going to be set to false and then blank when we submit our form this also needs to be false so we don't want to allow a user to submit anything without an image now right away we're going to get this issue let's see what's going on here so this issue occurs because we don't have a library called pillow so pillow is just an image processing library that requires or that's required to do this so before we do that let's go ahead and set the name or the string value to description right here so we'll just do description i just want to make sure we set that and before we actually migrate it let's go ahead and install pillow so i just want to look up pillow right now so let's choose let's just do django and we'll just do pillow and this is what it is right here so go ahead and look up the documentation it's just an image processing library and we can just run pip install pillow and it's going to take that air away so let's go ahead and close out these cat pictures we'll leave bootstrap open and in here so i have my virtual environment on so let's go ahead and install it here so pip install pillow oh man i had this issue before so i don't want to resolve this in this video so let's go ahead and run it from my command prompt so for some reason i keep getting issues when i'm in vs code so let's turn off our terminal right here and i'm going to open up my windows command prompt so we'll just search that up here we'll just do command so i'll just drag this in here it's going to be a little bit annoying because i have to go back and forth now but i just don't want to resolve that issue right now it's been coming up a couple of times here so let's go ahead and i'm gonna cd into my application here so don't worry about this i just need a cd into desktop here and i called it what did i call the app here so photo share so cd and then we'll just do photo share okay so i need to turn on my virtual environment i call that my env and then we'll just activate that so scripts forward slash activate okay so now we're back and i can just do pip install pillow okay so now we're just running that from our command prompt pillow is installed so if i go ahead and turn on my server now so do python manage dot and we'll just do run server let's see what we have here so the issue should go away so we have set null to true on a field where delete the delete rule is occurring so let's see set null what field is it telling us to apply this to so category so let's go into category let's see what's causing this oh it just requires a null value so so because we're allowing on delete to be true right there uh we just want to set that so we'll just do null that should be true now so i'll save that and let's see so now the issue goes away and we should be ready to complete this so for description i actually want to change this to a text field so let's just do that we don't want to do a character field let's just do text fields so we're not limited to anything and that seems more appropriate so i can get rid of all of this right now and we need to run our migrations so we have our two items here so let's go ahead and turn off our server i'll just do python manage dot py so let me zoom in here if you can't see that so i'll just zoom in a little bit and that should be good so python manage dot py run server or not run server so we're just trying to do migration so we haven't migrated our database yes so manage py make migrations so that's going to prep our database for the migrations and that's supposed to be from manage dot py make migrations okay so we prepped our migrations if we go back in here we can see migrations this is all prepping the database now now we actually need to migrate it so when we migrate it we're going to create the database and add these tables right here so let's just do python that's manage dot py migrate okay so we're migrating the database we created all the tables we don't have a user and i want to access the admin panel so let's go ahead and create a user so we can access that right away so do python manage.py create super user and we just want to run a few commands or we want to use the admin panel to add a few items to the database just to get things started and then we'll actually create our own form to create some items here so we'll just do dennis at email.com okay so i'll create my password repeat that again here we created the password now we can run our server so let's go ahead and run the server we'll go into the admin panel so if i go to the admin panel we shouldn't have the models yet so we need to register those but we do want to log in so we'll just do forward slash admin i have my user the password should already be there so we can't see our models yet so we just created those so we need to register them with the admin panel so we'll go into admin dot py the first thing we want to do is import the model so we'll just do from our directory here we'll just do from.models and we just want to import let's see we'll import photo and category and then we just want to register those so admin site dot register so we'll just register those and we'll just register the category we'll do that first and then we'll just copy and paste that and we'll register the photo so now if i register those if i go back to the admin panel we should see the photo in the category let's see what's the issue here register is that supposed to be lowercase i think that's supposed to be lowercase yeah so register was misspelled so that needs to be with the lowercase r we'll fix that right there let's go back in here make sure the server's on so run server again okay and that should do it so right now i can create my database objects here so let's go ahead and create a few photos and i want to show you where these get uploaded to before we update the static files here so if i go into my photos here we won't create a category yet so we'll go in here and category is required at the moment so let's go ahead and just change that really quick so we'll go into my models here in category we'll just do blank and that should be true so we don't need a category so we'll just do true here and i think i need to rerun my migrations here so let's go ahead and try that one more time add photo okay so now we don't need one so let's go ahead and choose an image so i'll go ahead and grab one of these pictures we'll grab nature right here we'll add in a description so i'll just throw in some text here so before we update our files here or our static files this image right here by default we don't tell it where to upload so what it's going to do is it's going to just upload it into our django project and we're just going to see it right here so we want to upload it into a folder called static but by default right now it's uploading it here until we fix that so we'll go in here let's open that up and let's create the image so the database object was added and now we can see nature right here so we just uploaded it into our project and we want to change this so later on this will be in our s3 buckets but for now let's just go ahead and remove this right now and let's configure our our static files here so we'll go into our static files let's open that up we'll go into settings.py to configure the static files so we can go into our project here settings.py and we want to do that right here so by default we already have the static url so that's the url path to go into our static files and what we want to do here is first add in media underscore url so this is where the url url path is going to lead us to to upload any images here so we'll just set that to images and then we're going to we can close that with the forward slash so we'll wrap it just like our static so that means to get an image from our project we're going to have to go into let's say por 8000 then we'll just do images and then let's say cat.png so that's what we're trying to do here we're just setting that so let's go back in here and after our image url we want to make sure to configure our static files directory so we want to let django know where our static files are so we'll just do static files so static files underscore directory so static file durs and this is just going to be a list right here and we can set all the paths here so for this we already have a variable called bay stir and that is up here so we're just using base stir if you're using a newer version of django the old versions we used to use the os module so you can still use that but we can just set baster and we're going to point this to a folder called static so we don't have this folder yet so we need to create this and this is going to be inside of our application here so inside of our project so we'll just go ahead and create that right here so we'll create a new folder that's going to be called static and now we're going into the base directory so right here and we're pointing into static so that's going to tell us where all of our static files are now we also need to set something called media underscore root so that needs to be root like that and what media root does is here it tells us what what media root does here is it tells us where to upload user uploaded content so in models.py when we upload this right now it doesn't know where to upload it so we saw it upload right here so we're just going to tell it where to upload these files to so if we go into settings.ui so let me close out a couple of these pages here we'll open up settings.py so for this we're just going to point it to the base directory so we're saying go back in here and then go into a folder called static so we're just saying go to static and then go into a folder called images so we need to create that so let's go into static here and let's create a new folder and we'll call this images so now we're telling it upload media files into this folder now there is something called static root that we can configure so we won't actually use this in here but i just want to show you since we are working with static files so static root there's a command called collect static and it basically bundles up all our static files into one folder when we're ready for production so what's going to happen here is we want to send that to a folder called static files so if we don't have this folder it's just going to create it and if we do then it's going to take all of our static files and throw them in there so the first thing i want to test out is media root so let's go ahead and make sure our server is on so we're running good here let's go ahead and upload a new image so let's open up the text editor and we're going to see the image upload into this folder now so let's go in here we'll go into that same photo and let's just add in another picture here so we'll just use the same picture we'll go to nature and before i save it let's go ahead and see what happens so let's make sure it's open here and when we hit save instead of adding it right here we just added it to this image folder so we found static and then it found images and we also needed our base dirt right here or not based here but static files dir to let us know where our static files even exist so that's not it we still need to do a few other things here so we want to configure our static urls here so if we go into urls.py so that's inside of photoshare so inside of our project we need to configure that so if i want to open up this image here let's see where the path is right now so currently we don't have any route to find it so we're going into images and then the name right here but we still can't find the image right so we set it right here and it should find that so we need to configure our media urls here with our urls.py files so before we do that let's go ahead and set this or make some imports so we're just going to do from django dot urls and we're not from urls but from comp here so from config let's import settings so we want access to the settings.py file so we just want to import that and we also want to import a function called static so we'll just do from django dot conf dot urls dot static so urls static and let's just import the static function so this is how we can configure it so we have these two and we're just gonna add on to this url pattern here so let's go ahead and do url patterns and we can just append to that so we'll just do plus equals here we'll use that static function that we just imported and in here we're going to go ahead and set that media url here so we're going to tell it to look for this file path so in here inside of the static function we can just do settings so settings and then we're going into media url so that's how we got that we're pointing to this now and we also need to let it know what folder to look into so when we go to that route we want to go to document so document underscore root and for the document here we want to go into settings so settings dot media underscore root okay so what happened here is we use this url here and we're letting it know that when we go to this path go ahead and go into static root or media root so let's see did i say static so media url media root go look in this folder and find our images in here so we have that image and that should connect to here so if i save this let's go ahead and save it and we can go ahead and actually go to this path now and now we can see the image so that's what that took care of for us here so if we wanted to configure the rest of our static files uh what we could do is we could just continue on with this right here we can just copy url patterns and we can also add in static urls so if we were using our css and javascript files this is how we would find that pad so now we're going to static url we're taking this and we're telling it to look into our static route so our static route right here so static route i promised you i'd show you that so what happens here is if we run collect static so this is when we're deploying the project we're not doing this now but we need to run a command called collect static so this is what django does in production so if i do python manage dot py collect static we're gonna see a folder called static right here so let's see okay so static files right here and it just created a folder with this name and it took all of our files inside of static so there's not that much now and it added in the image all the css and javascript for our admin panel so all the styling for this admin panel right here so we just bundled those up and it took care of that for us so now that we have that we're ready to start adding in real images and rendering them out in our template so let's go ahead and do that so we're tired of these cat pictures we want some real information here so we'll create some images from our admin panel and then later on i'll create a form to actually do this so you can see how to do this from the front end so let's go ahead and take care of that so in here let's go ahead and turn on our server so we'll do python manage.py run server and let's go ahead and output some data here so we'll go into our admin panel and the first thing i want to do in our admin panel is add in some categories so let's go ahead and add in travel for one of the categories so we can save that and now we have a category called travel so i want to output that in our template here so instead of this dummy data right here so currently we just have this right here and i told you would get rid of that so let's go ahead and change this so we'll go into our templates so in our app right here we'll go into templates gallery here and we need to pass in our categories into the template first from our view so actually we'll go back into our views and let's go ahead and get all of our categories so we'll just do from dot models so we need to query the data first so we'll just do from models import category and let's also import the photo so we have our database items here so our models and let's go ahead and just do categories okay so categories and that's going to be set to category this is how we can query them so dot category.objects.org so we just want to get all the categories and we want to pass them into our template so we just set a context dictionary here so context and that's going to be set to categories and then we'll pass in the query set so let's pass this into the template so we need to add it in as a third parameter so don't forget to do that we'll pass it in here and now in the template we can go into gallery right here and i just want to get rid of all of these right here so let's go ahead and first create a loop right here so we'll just do uh four category so four category in categories and as we're looping through that we'll just do and four here so and four let's go ahead and output each category so i'll just paste this one in here and actually close that out so let's go back to gallery so i just want to paste that in there and i want to get rid of these right here so our category we just have the value of name right here so we'll just do category.name and output that so we'll just go in here and now i can just do category so category like that and then dot name so now if i save that we should see real categories here so n4 didn't register this tag let's see what's going on here oh and i forgot the percent symbol right there so we just need to add that let's create some space here let's try that one more time so four statements should have at least four words here and we forgot in so four category in categories i was too focused on making sure to spell that right and now we see all and then travel so if i add in another category let's just say food so that's food like that then we should see another category so that looks good and we're taking care of that and we'll make these links later so we can actually filter those so let's go ahead and output the images now so we have let's see one photo here so we want to output that so let's go into our photos and let's see so that's going to be down here so i can get rid of all of these so let's take in this first column let's remove that let's remove the second one and we'll just keep one and then iterate over them so let's see so we have one column now so that's going to be one cap picture and let's go ahead and query the database for these now so we'll go ahead and do photos so photos and that's going to be set to photo dot object so objects dot all so we're just getting all of those so we'll pass in photo in here we need to set the equal symbol throw that in right here okay so we have our photos and now we can use those in the template so we'll create a loop right here so we'll just do four photo in photos so for photo in photos so the query set and let's create that n4 right here so we have n4 and i also want to make sure that if we have no photos we just say no photos so we'll just do empty so for some reason we have no photos let's just output the text we'll do that in an h3 tag and we'll just say no photos so that's only if we have nothing in our query set so no photos like that dot dot okay so let's see so now once we're outputting our photos i want to actually output the photo data so in here we can change the source right here so i can just do or i can just get rid of that cat picture and we'll use we'll just use a double curly brace and we can just do photo so as we're looping through it we're grabbing each photo we're grabbing the image the image attribute and as we output this this is going to be a little bit different than a normal attribute so we can't just do dot image because that's going to point us to the file so i'll just show you what i mean by here or by that so if i refresh that we're still not seeing it so we need to point to the image url so we're going to that url path for the image so now that i output it i can go ahead and go to inspect right here and we can see the image and then that file path here so what i want to do here is before we output all the images or before we add a few more i want to be able to view this image so if i go back here if we go into the actual photo page here we're just still seeing that cast so we want to output the image description and the proper image that goes with that so let's go into our photo here so photo.html need to go to our views here and let's just take in this query set so we want to change that to photo and in here we're just going to do get and then we want to get it by the id so we're just going to get that by the primary key and we want to pass that into our template so i'll just create the context dictionary like that so we'll just do not context but we'll just do photo and then in here we'll just do we'll actually pass in the photo here okay so before we can view the page now we need to make sure that in our gallery we're outputting the category and then linking up the photos so let's just do photo.category so photo dot category and we can actually get the name of that category so we can query up to that model right there and get the name and then in here we can just do photo dot id so that's how we know which id to link to so if i refresh this we should see the category updated so we don't have a category for this photo so let's go ahead and add one so in here let's just add in uh food here so save that i guess travel is more appropriate so we'll save travel and there we go so we see travel now when i click on it we get passed in the id of one and we want to change this image here so in our views.py file we query that we pass that into the template so we can go to photo.html and we need to do the same here so we need to change this image and let me just zoom back in here so we'll just do i'm going to use double quotes here so we'll use the double quotes and we'll just do url actually that's a i just realized that's an image so it's a it's a photo here so we can use the double curly braces and i'm just going to do photo dot image and we can just do the image url so for the description i want to pass that in so that's going to be photo.description okay so we have the description and we link back to the page and that's pretty much it for the photo page so now we can see the photo if we go here we can see that that checks out let's add in another one so we'll just do category we'll set that back to travel and let's add in another travel picture so get this forest looking picture here and we'll just use lorem ipsum for the description we'll paste that in right here save that so now if i go back here we still see travel and we have our second picture so when i click on this now we're seeing the picture with the description so up until now we've been using the admin panel and we want to do this from here so we want to see all of our photos we'll add in search in a second here but we want to click this right here we want to do add photo and then actually add in the photo itself so let's go ahead and build out that page now so we can close out photo.html i'll close out my urls here i guess i can leave my models open for now so in here we're going to start working with this view here so we need to send data here along with the image that we want to add to the database so let's go in here and we'll go into add.html and let's see if my template or my tag right here works so for some reason when i'm typing this in it wasn't giving me that so we'll just do ht ml and there we go so i don't know what that issue is i've been having a few issues today so let's just do add photo for the title and in here i also want to make sure i add bootstrap because we are going to be using some bootstrap styling so we'll go to this other page let's grab in that bootstrap css link right here and let's see so we'll just add that inside of my header tags and the first thing i want to do is add in some padding to the body here and we'll add in a container so we'll just do class and that's going to be m five we'll create some spacing here and inside of the body itself here let's go ahead and build this section out so we want to create a container so we'll just do div here so we'll create a div give it the classic container so i also want to make sure that this is going to be centered so we'll just do justify dash content and that's going to be center okay so we have our container and inside of our container we want to create a column here so let's see i'll just create a row here so we'll just do a div here set that to row and inside of this row let's create another div and that's going to be a column and i want to make sure that this form is small so there's no reason to make this form full width of the page so we're just going to do column and we'll set that to medium and we'll give it four we'll take up four spaces here so that's going to be a pretty small form here so we have that and let's just see what we have here so let's just do form save that and if i refresh that now we're seeing it so for some reason it didn't center that so let's go back in here so we have container justify content center maybe we don't need that row so let's try getting rid of this let's try that one more time okay so i see what i did here justify content was supposed to be on the row so let's go ahead and add in that row again so i can remove that div so the row opens and closes right here we have the column here and i'm just going to add in justify content to the row and not the container so i can get rid of that right there let's save it and that should do it okay so here we go and we just want the form in this section right here so it's a small form so let's go ahead and start building that out so in here inside of our column the first thing i want is a back button so we'll go into photo.html we'll just take this back button here so it should be styled and i'm just going to paste that inside of my column here so paste that in here we'll see a back button so when we create it let's say we don't want to actually build it out or we don't want to add in a form or a photo we can just go back here so we have that and let's create the form here so the form is gonna be inside of a bootstrap card so we'll create a div here and we're just gonna give this a class of card i can remove that angle bracket and let's just do card so that's gonna give us some styling here and for the form itself let's start creating that so we'll just do form and this form right here let's see i think i could just go ahead and get a bootstrap form so let's go ahead and find one here so we'll just do bootstrap components here so components and let's find a form okay so let's see we have a couple of forms here so i want a drop down list and a couple of text inputs here so i also want this field so let's just do this let's take in this form right here so the one with this choose file option and let's just paste that in here so we can get rid of those form tags we'll paste over them and let's see what we have so we have our first input fields here so we have that i also want to drop down select option so let's see for those inside of my form i have form group right here so we're going to wrap in every form group i'm just going to get rid of four right here i don't need that and let's just say upload image so we'll just build this out step one step at a time so just to upload image here the type is gonna be a file form control everything checks out and i'm just gonna get rid of the id here for now okay so we have that field and let's just copy and paste this right here so we also want to label for our text field so for the input we're just going to say text here and then for the class i'll leave that as let's see so we'll just call this form control and not form file and in here we'll just say description so this is going to be the description itself so description i'll make sure that's a capital d for the label and that field looks pretty good so let's see i also want some placeholder text i'll do placeholder and this is going to say enter a description okay so let's save that see what we get so we have that description right there and let's just add in some margin to each field here so let's just do my here so we want to set not margin top and bottom but we'll just do margin all around so we'll do m3 right there and we'll put that to the second one so that should look a little bit better okay so that looks good so we want to add in the drop down select option so what i'm going to do here is i'll just build this out by hand so just underneath or just above our image upload field let's go ahead and build this out so i'm just going to copy this right here so let's copy this down here and let's change up the values here so this is going to be select a category okay so select a category and then the actual field itself this is going to be a select option so we'll do select here for the type we don't need anything here so what i'm going to do is just change this to name so the name is going to be category so let me just rewrite that so category and let's see so for our placeholder we don't need that it's a select option here we can get rid of this form control uh we'll leave that in here and we want to add in the actual options here so for this i just need to add in a closing tag so we have our select field and to output our options here let's go ahead and output the first one and then the rest will be done in a loop here so we'll just do option close that out here and for this the first one is going to be select a category so select a category i don't know why i can't spell category so i'll just copy and paste that and the value itself we want to set this to none so we don't need to set this but the way i'm going to handle things in the back end uh we're just going to set that to none and that's going to be a string value and then we're just going to do select category dot dot and before i forget we do want to make sure to add in a name value to all of these fields so this is going to be description and this is how we identify it in the back end and then this one's going to be image okay so we have our category options let's make sure that that drop down field is working but we don't have many options here so i want to make sure the category options are what we have right here so let's go back into our view and in our view i'm just going to take in categories right here we'll add that to add photos so let's fix that indentation here and i'll just go ahead and take this context dictionary and we can just remove photos here so we'll get rid of that let's add in context into the template here and now that we have categories we just want to loop through and output all of those options here so we'll just do let's see let's create a for loop so we'll just say four category in categories so we're looping through the categories let's add in the n4 here so we'll just do and four to end the loop and let's take in this option right here we'll paste that in here so we're just iterating through it and the value itself is going to be the category id so we just want to pass that in so we'll just do category id and that's what we're going to send to the back end now as we select it we do want to see the category name so just do category dot name so we're just outputting those and we're sending that to the back end so let's see so go to add photos we can see travel food and there we go so everything looks pretty good so far what i still need is my submit button here and i also need the option to select or to create my own category so if i for some reason don't want to select one of these let's say we want a new category called family i just want to be able to create that so let's take in this description right here so let's take in that entire form group and i want to paste that underneath my drop down select option so we'll paste that here so we'll just say create a new category so create a new category and in here category let's see so i always misspell that and for the name itself we'll just say category and then this is going to be underscore new so in the back end we need to look for this value and then we'll just say create a new category so for the placeholder okay so now we should have that option that looks good so let's go ahead and finish up this form by adding in the button and then setting up the form request type here so in here what i want to do is just create a button here so we'll just do button so we'll create the button here and then the type is going to be a submit button so when the form is submitted this is the button we're looking for so submit here and then let's go ahead and just say submit and give it some styling so we'll just say submit here and then for the class let's just do btn and then btn primary so that's going to give us a blue color so primary and then after that uh let's just set it let's set some margin here so we'll just set that to m3 okay so that looks good and for the form itself here we need to add in the values here so the method here we're sending a post request so we're adding data to the database so we'll set that to post and then action because we're just going to send this to the same url we can leave this blank so i could add in this url here but by default if we don't have anything in there it's just going to send it to this page here so we know where it sends now so if i save this now what we want to do is also send in some form data or not form data but some files with it so in a normal form let's see where's the top of my form let's create some spacing here so in a normal form we can just send it like this but because we are going to send in that image what i need to do is add that value in here so we'll just set the ink type here so we'll just do ink type and this is going to be multi-part form data so multi part form data just like that so multi-part forward slash form dash data and now it's going to send the form fields with it along with that image field so now in the back end what i want to do is go ahead and get that data and then create it and i need to add in some conditions here too so we have our categories inside of add photo and underneath our categories once we get this data what i want to do is go ahead and check the request type so we're going to just create a condition here and we'll just do if request dot post or if we request dot method if this is a post method which we are sending a post request from the form so if the value is post let's go ahead and create an image here so before we do that we first want to get our data so our form data and this is going to be set to request dot post right here so we're going to the post request and let's see so we just want to set that value that's data and we also want to get the image so we'll just do image here and this is going to be request dot files so we're getting files and we want to know what file to get so we're just going in and grabbing the image so in our form we sent this field right here or we're sending that with a name of image so we need we need to look for image here so i'll save this too let's make sure to get that so we have the data here and let's go ahead and just print this out first to see what's happening here so if i print out data so print that out as a string and then the actual values and let's do this for image so let's see fix that indentation add an image here and let's see what we get here so i want to send this form data and i want to have my console opened up here so let's go ahead and move this to the right here let's open this up here so request.method equal to post it looks like i'm setting an assignment so i need to do equals two like that and that should fix it so let's go ahead and send something so if i move this to the right let's send the data so let's just type in some values here let's set travel the category upload an image and let's hit submit okay so it looks like it sent it as a get request so i think we didn't refresh the page so let's see our method here that's post so let's go ahead and just refresh the page and try that one more time so we'll go back here go to add photo continue with this and i want to actually make these fields required so the description should be required so we'll just do required here and then for the in the image field here we don't want a user to upload an image or submit this form without actually uploading the image itself so i'll save that and then let's refresh that so let's go back into here let's create something so if i try to submit that without it we should see this field is required and we'll just say new photo let's select a category so just set that to travel choose an image we'll do nature one submit that and it looks like we're missing a csrf token right now so we can't send a post request without a csrf token so let's add that csrf underscore token okay so now it should work let's see if i get any more issues here so i'll just go back here refresh that add in some data we'll just say new image select a category travel add in nature and let's submit that so if we look at our request here we can see that we're printing out first our data so we get a query dict right here we see our csrf token we see the value of the description which is new image our category and that's just the id of one so that's the travel category we're not creating a new category so it's just an empty string and then we see the actual image file so we can go ahead and write a condition and create this now so let's go back in here into our views and the first thing i want to do here is go ahead and check if we have our category set correctly so we just want to check our data so we're just going to look into look into data and remember we send category so we'll just check that so we'll do category so if category right here is not equal to none so remember the default value right here if we don't select a category that's going to be none so by default we're sending the value of none so that's a string value we can't just use none like that it's a string value like that so we're checking it if we don't have a category then let's go ahead and or if the category was selected so the value is not none then let's go ahead and find the category so we'll just do category so category and we just want to query that so we'll do dot category.objects.get and we want to get it by the id so we'll just set the id value and that's going to be set to data dot category so we're passing in the id now if we don't have this we'll just create an l if statement so we'll just do l if so if the category new value was sent so let's say uh the value is none then we want to go ahead and check this condition now so we just want to do data and we're going to pull out category new so that's how we sent it from the front end and that's the form field that we fill out manually so we're going to check category new then what we want to do is we want to see if category new is not an empty string so if it's not an empty string then what we want to do is go ahead and create a category here so we can set the value to category and because we're going to use the function get or create we need to set the return value and then the created value which is just going to be a true or false value so don't let that confuse you if you haven't seen this yet it's the same as assigning a variable except for we need this extra value now in here we're just going to do category objects dot get underscore or create so what this is doing is it's going to look for the category with a certain value if it doesn't have it it's just going to go ahead and create it and add it to the database so in here we're going to look for a category that has the name of category new so if that's in our database then we will find it and add it if it's not we'll create it and then set the value to category so all we're doing is setting the category or creating one if we don't have any categories now it's okay for an image not to be in a category so we'll just say category and that's going to be set to none so set that to none and that's it for that so once we check the category now we just want to actually create the photo object here so we'll just do photo and that needs to be a lowercase f so photo is set to photo dot objects dot create so we want to create that and we want to set the category first so that's why we had to query that so remember in our models we have a parent child relationship so we just have to set this value so we'll set the category to categories so it's either going to be a category in the database the newly created category or just none and that's okay if it's not a category so after that we want to set our description so we'll just do data and then this is going to be description and i keep doing curly braces so description okay so let's see okay i couldn't spell description there so we have the description and then finally the image itself so this is going to be a file here so we get that inside of image right here we do request.files.get we get the image and then we can set that so let's go ahead and test this form out and this should be it for now so before we actually test it i want to make sure that when we create a full a photo here so when we add a photo we want to be redirected back to our home page so to do that all we have to do is go up here and at the top of our views file after render here so from django shortcuts we'll just do redirect and we can just redirect to that page so if it's a request dot post method if everything went successfully we'll just do return and then redirect so for redirect we just want to send a user back to the gallery so we'll just pass in the url name here and let's refresh it and go back here so we'll go back to the gallery it looks like we have an issue so let me just restart my server it looks like it froze up there okay so i can go back here and let's go ahead and add in a new photo so right now what i want to do is add in a photo here so we'll just say let's actually just use lorem ipsum i don't like leaving that blank so lorem ipsum we want to add something to food now so we'll go into food we don't want to create a new category so we'll go into photos and remember you have all of these photos i'm going to leave these in the github repo so let's grab in or let's grab this picture submit that and we just added it to the database so we sent that data back here we ran these conditions we submitted it and it redirected us so now if i go to view this picture we can see that photo we see the description and let's go ahead and add in a picture that doesn't have a category so we want to add one without a category so just paste that we won't select anything we'll add in a new picture let's see we'll just take something from the desktop here i'll just take in this favicon looking picture submit that and now we have no category but let's say we want to try submitting something that doesn't have a category yet but we want to create one so we'll just add in that dummy text we'll go ahead and write in a new category so we have travel food and let's just do amita and dennis so and dennis so this is me and my wife let's say i want to upload a whole photo album for that so we'll go into photos here and that's currently under family so i want to upload this submit that and there we go so we have our new category now we can see that in here so if i go back here we'll paste in the description now we see so amita and dennis and let me just add in a new picture here so there we go and everything's looking pretty good so before we move on to adding these photos into aws so they're currently stored right here inside of my static files so we see them being uploaded and that looks good but i want to start sending them to aws so before we do that i want to make sure these search filters work right here so let's go back into my gallery template here so we can close out add.html photo.html and we'll go into gallery here so in gallery i want to make sure we can wrap these links or these right here inside of link tags here so we'll just go in here and let's see so that's my left column so right here inside of this card called categories let's go ahead and first get that all linked right here so in here we want to be able to reset the links themselves so we'll just go ahead and wrap all here and we're going to put that inside of an a tag so let's see let's move this down here and we'll just say a close that off let's just add that around it so for the actual link here so let's just do href here and let's point this to the home page here so we're just going to point this to url and i need to wrap that in quotes so we'll just use double quotes here wrap that and we're going to url and then the actual name is gallery so this is the current page we're on and this is meant to just reset it so if i go here if we just refresh that and we'll fix that decoration or that styling right there so we want to make sure that's black and no underline so that just takes me to this page now for these right here i want to send the user to the same page here so i want to actually wrap this again and let's remove that extra quote right there but what i want to do is i want to send in a get request with it so i want to send in an extra parameter so in here i'll just paste that let's remove that closing tag wrap that around the name and for this all we're going to do is after the url here so we're going to the gallery page we're just going to add in a question mark so that's going to be the get parameter right there and let's see so i just want to call this category so we'll just do category so category like that and we'll set the value to the category name here so we'll just do curly braces and in here we'll just paste in category.name okay so we're going to the url we're adding in this right here and then the name of the category itself so let's just try that so it's not going to filter it just yet and let's see what did i do wrong here oh it looks like i messed up the actual link here so let's see category name close that a tag okay so that looks better okay so i'll just move that down here so we can see that it's wrapping it and if i try that one more time we should see the name now so if i go to food now we're seeing the same url with the question marks the get parameter category and then food if i go to solimit then dennis that looks good right there we have travel and then all to reset it so when we send this request we're refreshing the page that means we're calling this view again so this view right here gallery we're calling this so we just want to customize this to actually get that data so let's go ahead and add this in here so the first thing we want to do here is we want to get that category so we just want to do category so category like that and to get this we're just going to do request so request dot get so i don't know why request looks funny so i spelt it right that looks good i don't know why it's doing that so we're going to the get request and from the get request we want to get the category itself so we just want to get the category as a string value so we're sending this so we want to get whatever this value is and that's going to be the value that we pass into it so if i save this let's go ahead and print it out and see what's going on here so we'll just do category we'll paste that in as a string value and then the actual value itself so i'll save that let's go in here and let's try that one more time so we'll just do travel so we see category and we just see the string value and then dennis and sula mita so that's just sula amita right now that might give us a slight issue maybe i can make the categories in one value because it's calling that ampersand right there so then we see food and travel so let's go ahead and do that so now we see none so if i do all we're not getting any data so that's what we need to check for right here so the first thing we want to do is check if we have any data inside of categories so let's write a condition here and i can just remove this right here so i'll just get rid of that and we'll just say if category so category is none so that's equal to none then let's go ahead and return all the data so we just want to take this right here we'll paste that fixed indentation okay so we just want to get get all the data here so if we do have some get data we just want to write in our else statement and we want to filter this data now so let's just take in category we'll paste that in right here and for category instead of getting all the data we'll just do dot filter and what we want to do here is we want to go ahead and filter it by the category name so we'll just go into our objects here okay i just realized we did the wrong one here so that looked funny to me so we have our photos and we have our categories so categories is still going to be all so we're just going to add that above our photos and what we'll do here is we'll add in the photos here and then if we want to get that data and we have some parameters we just want to do dot filter like that so the photos not the categories now inside a filter what we can do here is we can just go into the category so we'll go into category remember the photo has a category as a parent so what we can do is we can just do category underscore underscore so double underscores right there then we'll go into the category name and we'll just do underscore underscore again and we'll just do i or we'll just do contains so if it contains the value that we send in the get request then we just want to go ahead and get that data i mean filter that data so we'll just pass in category right there and i think i can actually do this with equals so we'll just do equals like that so if the category name is equal to what we passed in the category are in the get request and that should work so let's try this so if i go to travel looks like it's not working so let's try the contains method and we'll just try to fix this in a second so let's just do contains like that we'll try this again oh and it looks like i'm still querying all the photos here so let's try that again so i want to set that back to equals and that needs to be a single equals like that and let's see this so if i go to travel now we see only travel here if i go to food we see the category as food and if we go to all we get all the data so let's try selamit and dennis for some reason that's not working i'm going to test that out in a second here but what's happening here is as we send this get get parameter right here if we send none the value itself back here is going to be none right here so we if it's none we just go ahead and return all the photos if we do have a value for category in that get request we go ahead and filter it by the category name so i think the issue is because i have this ampersand right here so let's just go ahead and do this so we could write something in to limit that but what i'm going to do here is i'm just going to change the category and i'm just going to say and like this so let's just do s that should fix it so now if i go ahead and search that it will go to all sulamita and dennis and there we go so that checks out and that's how we add the photos search the photos and filter them and it's a pretty simple little application and it looks pretty neat so i hope you enjoyed it so far if you're ready to go ahead and move on to adding this to our aws s3 buckets go ahead and stick around we're going to take care of that in about or i guess the next couple of minutes here so what i'm trying to do here is i want to make sure that all of these images are uploading to aws s3 so django is not built to store static files in production it's good for testing but later on we're either gonna have to use a third-party package uh one we can use something called white noise for that so white noise takes care of static files for us or we want to store them completely separate when we upload this to a server so if we put this up on heroku we don't want our static files being delivered from our django application so let's go ahead and just go to aws so i'm assuming if you're following this part you already know what this is so this is amazon web services if you don't have one if you don't have an account go ahead and create one you will need a card on file to use this but we want to use the s3 buckets option here so there's different services we can use and i'm going to use the s3 bucket so i'm just going to log in here and i'll just go ahead and type in my information so i'll probably blur that out here just in case and we're going to s3 buckets so go ahead and search it so i already have it in my recently visited options here so we'll go to s3 find our s3 buckets so just go ahead and open that up and in here we can just store any kind of files here so the first thing i want to do is i want to create a bucket here so if i go to create bucket we can create a new bucket so we'll just call this photo share and actually we'll just call that photo sharing we can leave it there the first thing i want to do is give it the bucket name and i want to make sure that we can have all public access so we can see this data from a live website so go ahead and acknowledge it there are certain security things you should look out for but for hosting files up for a website it's okay to just host our photos and upload them publicly but if you have any super private information make sure that that's not public right there so let's go ahead and go in here leave everything by default so i can just leave this and let's go ahead and create the bucket itself so looks like somebody's already created the bucket called photoshare so we'll just do photo share and then dash bucket let's try that let's see if that works okay so we created the bucket and we have it down here so let's go ahead and find it so photo share let's see where was that photo share bucket so right now you'll notice you have this uh we have this right here that says objects can be public so we're allowing that but we still need to add in some permissions to really allow those objects to be public so it means that we're prepped for them to be public but we still need to add in let's see if we go to properties here or permissions we need to add in a bucket policy that allows our objects to have uh read options so that means users can view the objects or the photos or any kind of files we have in this bucket so what i'm going to do is i'm just going to go ahead and grab a policy from a different bucket here so i'll just grab one here and i'll link it up in the source code so you can just go ahead and take it there's a bucket policy generator that we can use so let's see i'll just go to another bucket we'll go into permissions here and we want to take this policy right here so let's just take that i'll leave that in the github repo then let's go back into our photo share bucket so let's see photo share so photo share bucket will go into permissions and let's go ahead and paste that in here so there's a bucket policy generator we can use that can set all these but for now we're just we'll just paste this in here so we're just saying allow public read let's go ahead and allow users to get data so that means they can send get requests and we need to add in the bucket name so for resources leave all of this leave this closing forward slash and that right there and we'll just say photo share so the bucket name so photo share and let's go ahead and save that so this is going to allow all the objects to be public permanently in this bucket so now we're seeing this alert it's just saying that hey don't put any super sensitive data in here we want to make sure to get that alert and know if a bucket's public or not so now that we have a bucket we need to access this bucket from our application so we want to be able to upload data into this bucket access it and just make certain requests to that so let's go ahead and find that i'll just do photo share so we can find that easier so here's our bucket but in order to access it from our application we need a user to be able to actually be authenticated for this so i'm going to delete this bucket right after this video so i'm not worried about you seeing certain access keys but let's go ahead and go into our services again so we'll go back here and what i'm looking for is my i am user so this is basically a user to your aws account and you can have different users that have different level of permissions and what i'm going to do is i'm just going to create a new user so go in here we're going to add in a new user and we're going to give this user the ability to access our bucket so we'll just say dennis dash photo share so that's a user for our photo share bucket i'll go ahead and add it we'll give this user programmatic access so go ahead and set that go to next here and the bucket policy let's see so we want to do s3 so we just want to search different policies and we want to select amazon s3 full access so go ahead and select that so the user has full permission to this bucket let's go ahead and continue here we don't need anything here and now we have our user or we're about to create it we see the access level and let's go ahead and hit create user so now that we have our user we see the user we see the access key we see the secret key i'm going to show you this information and then i'll delete the user but let's go ahead and go into our application and configure our application to actually access this so this is why we need a user i'll leave this page open here so let's go into our application now so we'll go in here we'll close out everything and we'll go into views.py so we'll go into not views but into settings.py so in settings.py right now our data is configured to upload into my static files right here so we're just going to change this and the first thing we need to do is we need a third-party module to actually interact with our bucket so with this we want to install something called django storages and boto3 so let's just do pip install so pip install and we'll do both three and i'll pull up the documentation in a second so we have boto3 and then pip install storages so i believe that's django storages okay so we have django storages we have boto3 so let's look that up we'll just do django storages okay so django storages here's a package here and it tells us how to work with different types of options we're going to select the aws s3 option so you can see his pip install django storages and then to actually configure it go to amazon s3 and here are all the things we need to configure to actually connect to our aws account and then we have boto3 so boto 3 aws or django so storages needs boto3 so we need to make sure we have this too and it pretty much gives us the same setup and what we need to do to actually access it so there's a lot of these different variables and parameters that we need to add or there's a few that we need to add and then a lot are optional so let's go ahead and add these in so we have that installed we have storages boto3 i'm going to turn on my server so we turn on our server and the first thing we need to do is add in storages to our installed apps so we'll just do storages so we added that and now we can use that so let's go down here underneath our static files and the first thing i want to do here is configure my bucket here so we'll just do default and let's actually look this up so i'm just going to go in to storages here so i'll close out both three and let's look that up so default file storage so we need to set it to this value right here and this just tells us that we're gonna use boto3 and storages to connect to a bucket here so all i'm gonna do is paste that in default file storage that's storages backends s3 and then boto3 storage now after that i'm going to go in here again so i want to go to the documentation let's go ahead and look up our access key id so we'll just do aws underscore actually let's do control f aws underscore axis key id so this is the amazon access key and then or the access key right here and then your id so this is for that user we just created so let's take this right here we'll paste this underneath so aws access key and let's go ahead and get aws secret key so we'll paste these in here and we want to set these values so i'm going to delete this after this video but here is our access key so we'll copy that i can go ahead and add that in right here as a string value and then i want to go ahead and get my secret key so i'm going to copy that right there and let's go ahead and paste this in so we don't want to show this normally you want to store this in environment variables make sure this is hidden when you're going to production but here we go so we're letting it know that we're using storages we have our bucket and then the last one we need is going to be the actual bucket name so we have the user now this user has permission to access any bucket in our database right so what we need to do here is go into aws and then this is going to be storage so we have storage i don't know why it's not finding it okay so here we go so aws storage bucket name so let's go ahead and add this value in here and this is gonna be the name of the bucket so what did i call this bucket here so the bucket name itself if i go to s3 again we'll go back to our buckets and what i want to do is find the bucket here so this is going to be photo bucket share and that's the name of the bucket so we want to tell it to get this bucket so this user right here this user with all these credentials i'll create the spacing here this user has access to this bucket so we're just telling django hey now we want to upload it to an aws s3 bucket now the last thing i want to do is add in something called aws underscore query and then so query string and then underscore auth so we need to add this to let it know that we don't want to add in extra parameters to our url for our bucket items so i'll show you what that looks like in a second so let's go ahead and save that and actually want to paste that let's see i'll just paste that at the top here so let's see what happens now so we have our bucket we're connected and false needs to be like that so false so let's save it and test this out so we have our bucket we see there's nothing in here so i'm going to close out bootstrap we'll close out all of these pictures and let's go into our gallery right here so i want to add in a new photo let me turn on my server okay so run server and it looks like we have this alert so let's just go ahead and look up aws default acl so i remember seeing this i just can't remember what it was so let's just do aws default acl so optional default none which means that the file word will inherit the bucket's permission so it looks like i don't need to set that then if it's telling me that so it's just a warning i'm going to leave it here so if we look at our application right now we just told django that we want to serve our images from our aws s3 buckets so that means that these images if i look into them they're looking into the bucket now and not into my static files so what i could do is i can go ahead and go into static here let's see so let's actually just try this i want to show you how this works so we'll go into our bucket and let's go ahead and upload one of these images here so we'll go into photos so photo share this is my project we'll go into static and let's just grab this picture right here so we'll take in family or family five here so that's the name of the image and i'll go in here so we'll just go into upload and we're gonna upload this picture and let's see so in here we'll just do add files so go into family five open that up and let's go ahead and upload that file so if i close this out right now django right now is looking for the file on aws s3 bucket so it's looking for this path so if i go to this file you can see this link s3 s3 object photo share bucket and then the bucket name so if i refresh this one of these should be that file so i guess the name wasn't renamed so let's just try this really quick so let's go back into our admin panel let's just update that so let's just do forward slash admin let's go to photos and maybe this should be changed right here so let's go to travel nature 3 that was a picture so nature 3 save that okay so if i refresh this nature 3 is updated so it looks like when i uploaded this picture right here for some reason the file path wasn't correct here so what happened here if i go back to my bucket we can see nature 3 right here so we went in here we uploaded it so when we added that inside of our admin panel let's see so we went in here i'll close out storages we added that image so when we hit submit instead of going into my route right here the static route or the let's see the media root instead of going in here because of these configurations django uses this user information it accesses that bucket uploads it to aws and now all of our images are stored up here so let's go ahead and remove some images and we'll just add them by hand again so we'll go into photos we'll just remove everything so the images are still up on aws s3 but we're just gonna have to reset it so we have no photos right now we'll go in here and i just realized the styling for that link looks kind of ugly so let's go ahead and fix that really quick so in photos and template we'll go into gallery and we'll go into style right here and what i'm going to do is just get the list group item so list group dash item and that was list dash group so that's just a class on each link right here so if i look right here list group item we're just going to grab each link right here and we'll just set list style that's going to be none so that's going to remove the underline and then color we'll just set that to black so we'll just do color and i'll set that to black here okay so i'm gonna save this and that should fix that okay so the styling looks better and that's not list style but text decoration so text dash decoration okay so there we go so let's add in some new photos so i'm gonna go in here let's just paste in some lorem ipsum here so we'll just do lorem ipsum let's grab that copy this right here and let's add in a photo so we're not using the admin panel now we're using this so we'll add in the description we'll set travel here we don't need to create a new category so let's go into travel and let's set the first one so we'll create one for travel okay so now travel should be uploaded here so we uploaded it to the bucket and that looks good so if i look at the image the image link here so we'll just do let's see open image a new tab we can see that this is pointing to that s3 bucket so if i deploy this anywhere publicly the amazon web services is gonna or the amazon web services so the s3 bucket is what's serving this so for the rest of the video all i'm gonna do really quickly is just add in some pictures and that's it for the actual tutorial so that's the entire application we have all of our search functionality we have our add photo option and we're uploading this to s3 buckets so i hope you learned some styling maybe how to use bootstrap and how to connect all this so let's go ahead and just finish this up so we'll just go to travel here let's see we'll just add in this picture from new york here this is a trip that my wife took last year that's in travel and we already have that so let's submit it okay so i guess it didn't upload it so travel and then i want to upload some pictures of me and my wife so this is a personal album for me we'll go into see so let's go back to photos so we have photos and i like this picture we'll save that there's another picture from greece that i really like so i want to add in the description go to travel and we'll just do this one right here so this is probably my favorite one actually from greece so if i view that i want to make sure the sizing looks good okay so that picture was uploaded so let's go in here we can see the picture here and that's from a beautiful place in greece and that's going to be it for now so we have our search functionality we have no photos of food here if we go to travel we go to solamite than dennis okay so everything's looking good i hope you enjoyed this tutorial i do have my my udemy course out on react and django so if you go to buildproshop.com i'll definitely recommend checking this one out so this is a website it's a fully functional ecommerce website with jango and react if you want to find that on udemy click on this link right here and it is a paid course so i hope you check that out i hope you like this tutorial i'll see you guys in another video
Info
Channel: Dennis Ivy
Views: 26,028
Rating: 4.9651418 out of 5
Keywords: Programming, Software Developer, Dennis Ivy, Dennis Ivanov
Id: sSquD2u5Ie0
Channel Id: undefined
Length: 106min 59sec (6419 seconds)
Published: Thu Feb 04 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.