# Python Django Tutorial: Full-Featured Web App Part 9 - Update User Profile

## Метаданные

- **Канал:** Corey Schafer
- **YouTube:** https://www.youtube.com/watch?v=CQ90L5jfldw
- **Дата:** 31.08.2018
- **Длительность:** 26:06
- **Просмотры:** 298,348
- **Источник:** https://ekstraktznaniy.ru/video/12121

## Описание

In this Python Django Tutorial, we will be finishing our user profile page. The final page will allow users to update their information and also add a new profile picture. We will also learn how to resize this image when it is uploaded to save space on our web server. Let's get started...

The code for this series can be found at:
https://github.com/CoreyMSchafer/code_snippets/tree/master/Django_Blog


✅ Support My Channel Through Patreon:
https://www.patreon.com/coreyms

✅ Become a Channel Member:
https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join

✅ One-Time Contribution Through PayPal:
https://goo.gl/649HFY

✅ Cryptocurrency Donations:
Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3
Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33
Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot

✅ Corey's Public Amazon Wishlist
http://a.co/inIyro1

✅ Equipment I Use and Books I Recommend:
https://www.amazon.com/shop/coreyschafer

▶️ You Can Find Me On:
My Website - ht

## Транскрипт

### Intro []

hey there how's it going everybody in this video we'll be finishing up our user profile page and making it so that users can update their information from this page and also upload a new profile picture we're also going to set this up so that our images are automatically resized when we upload them so that we don't have extremely large images on our file system when we're only displaying the small little you know 200 pixel images here on the profile so let's go ahead and get started so in order to update our user and profile we're going to need to create some forms and we've created forms in a previous video when we created the user register form for our register page so let's open up that user app form stop py file that we created in that video and we're going to create a couple of additional forms to update our user and profile so within sublime text within our users app we're going to open up that forms dot py file and within here we're going to create some additional forms so we're going to

### Model Form [0:57]

create something called a model form and a model form allows us to create a form that will work with a specific database model and in this case we want a form that will update our user model so let's create this so on a new line down here I'm going to create a new class and I'm gonna call this user update form and I'm going to inherit from forms dot model form and within this class this is going to be very similar to our user register form except we're not going to use the password and password to here so we only want to update the username and the email so I'm just going to copy this user register form here and paste this in and get rid of the password 1 and password 2 now in a future video we will have a reset password form where they can request a reset email for the passwords but they're not going to be able to update their passwords on this just their username and email for now so

### Profile Form [1:58]

by specifying these values here in the fields and let's our form know that we want to work with the username and the email within this user update form but you can see that we don't have the profile picture here yet and that's because that will be in our file model not our user model so we actually need to create an additional form but since we'll be working with the profile model we first need to import that so here at the top I'm going to say from dot models import profile and now we can create that profile form so I'm going to call this class profile update form and I'm going to inherit from that forms dot model form and now we don't want to add any additional fields here so we can just jump straight into that class meta and within that class meta we can say that the model that we want to work with is profile and the fields that we want to work with this is still going to be a list but it's only of one value and it's going to be image okay so now we have two forms here a user update form and a profile update form and the user form will allow us to update our user name and email and the profile form will allow us to update our image but whenever we actually put this on the template it's going to look like just one form okay so with those forms created let's open up our views so that we can add these forms to our profile view so I'm going to open up our user app views here now first let's add the

### Import Forms [3:33]

forms that we just created so let's import these so we'll import these from the forms module and we're already importing this user register form so now we can just add on the user update form and the profile update form and now down here within our profile let's create instances of these so for our user update form I'll just call this you underscore form and set that to a user update form and let me fix the spacing there and we just want to instantiate that as empty for now for our profile update form I'll just call this P underscore form and set that equal to a profile update form and now let's pass this in to our template so to do this if you remember we can create a context which is a dictionary and the keys are going to be the variables that we're going to access within our template so we can just pass in a you form variable here that is equal to our you form which is our user update form and I'll do the same for our profile update form so P underscore form is equal to our P underscore form and now let's pass that context into our template so that we can access those forms okay so now let's open our profile template and print out these forms now again we've done this once when we created our register page but it's probably good to go through this again but as a starting point let me go ahead and copy the form section of that register route so that you don't have to watch me type all of this again so I'm going to open up the register route so within our users templates I'm going to open up register dot HTML and

### Drop Forms [5:20]

I'm just gonna grab this form section here so from the opening form tag to the closing form tag I will copy that and now within our profile template so profile HTML I have a comment here that says this is where I want to drop my form so I'm just going to drop the form right there and then fix the indentations there and save that and remember from that video that we are using these crispy forms applications to print these forms out so make sure that you're loading those at the top of the template so if I go to we can see that I have this load crispy forms tags here now if you don't have that if it's not there for any reason then go ahead and add that in so those crispy forms will work okay so now let's go down here and look at our form okay so this is the form that we

### Add Forms [6:08]

created in the register page now within our profile template we're actually going to have two forms with different fields but we're going to put the fields for both of these forms into a single HTML form so that the user sees it as one so let's see what this looks like so I'm going to change this form to contain both of our user form and our profile form fields so I'm just going to copy this section here and just put it in twice and this first one here will be our you underscore form for our user forum and the P underscore forum will be the fields for our profile form and now also change a couple of other things with this form to make it specific to our profile page so for example our legend here says join today because that was our register template but now we want this to say you know something like profile info and down here with the submit button it says sign up but now we're going to be updating our profile so let's change this to say update and

### Encoding Type [7:11]

save that okay and one really important thing that I forget to do sometimes that always throws me off is to add a special encoding type to our form now we have to do this in order for our form to pass our image data for our profile picture properly so at the top of our form within the opening form tag here we need to add an attribute of ink type so that's a and C type and we have to set that equal to multi-part forged slash form - data and save that so be sure not to forget that if you leave that out then it can look like your form is working but it all that won't actually be saving the image in the background and that can be something that is kind of hard to debug okay so with those changes made let's see what this looks like in our browser to make sure that this is working so far so I'm going to save all of those files and open up our terminal here and it looks like we have an issue with one of our forms now it's saying that we don't have a fields attribute for one of our model forms now I don't think that is true okay so I misspelled fields here this needs to be fields and not field so let's save that open up this and now let's restart our server I think it might have trouble restarting there so now it looks like it is starting up without any errors so that's good and now let's go to our browser and reload our profile page okay so this is looking pretty good now right off the bat I noticed one thing important and that's that the fields aren't filled in with the current user information so if you're updating your user name or email then you're going to want to have your information filled in already so that you can see what it currently is and also we're not doing anything with this form information when it's submitted just yet if we remember when we submit forms it's going to do a post request back to that same route with the data from the form so let's address some of this in our views so if we go back to our user app views file within our profile view so first of all let's populate these regular forms with the current information of the logged in user and this is really easy to do so remember these are model forms that are expecting to be working on a specific model object so we can populate the fields of the form just by passing in an instance of the object that it expects so for the user update form that will be an instance of a user and the profile update form that'll be an instance of a profile so to do this we can just say when we instantiate these forms I can say instance is equal to and for the user update form that's going to be request dot user so that'll be the current logged in user and for the profile update form I can say instance is equal to request dot user dot profile to get that user's profile so making those small changes there will now populate those forms with the current users information so the user form user update form will have the username and email filled in and the profile form will have the current image filled in ok

### Check for Post Route [10:27]

so just like up here with our register route we're also going to want to put in a check to see whether this is a post route or not and if it is then we'll want to see if our forms are valid and if the forms are valid then we'll save that information so let me copy this conditional up here and paste this into our profile view so we'll say if the requests stop method is equal to a post then we'll go ahead and create some forms and if it is not then let's also grab another thing of forms here for now

### Post Conditional [11:03]

ok so within our post conditional is what will be run when we submit our form and possibly pass in new data so we want to pass in the post data into our forms so we wanted to keep the instances set like they are now because it has to know what user and profile that we want to update so let's leave those there but let's also pass in the post data so right here before the instance is set will say request dot post to pass in the post data and still leave the instances set so again request dot post and comma and keep the instance set and finally

### Profile Data [11:41]

with the profile form we're also going to be getting some additional data and this is going to be filed data coming in with the request and that will be whatever image the user tries to upload so right after the request dot post data will also add request excuse me I spelled that wrong request dot files and then put in a comma and keep the instance there and if any of this ever spreads out too far then we can always spread these up onto different lines so let me do that and save that okay so now

### Validity Check [12:16]

that we have both of our forms populated with the data that's going to be submitted then we can check if they're both valid now if they're not both valid then we're not going to save any of the data and again we're basically doing something very similar to what we did in our user registration form but now we just have two forms but the process is almost identical so we can see up here we said if form is valid but down here we are going to say and we're still within at this if request equals post conditional so this time we're going to say if you form dot is valid and P yes so if they're both

### Save Data [12:59]

dot is valid yes so if they're both valid then we're going to save the data but if one of them isn't then we're not going to say anything so now within this conditional we can simply say you form dot save and P form dot save so that'll save the user update form and the profile update form okay and that should be every that we need so once our forum information is updated then let's give some feedback to our user letting them know that they've updated their profile and then we'll also read redirect them back to the profile page so again this is very similar to our register route so I'm going to copy from here because we already have a success message and a redirect up here so I'm going to copy those and within this is valid conditional I'll paste those in and for the success message I will just say your account has been updated and then we want to redirect them back to the profile page and save that and you want

### Post Get Redirect [14:03]

to do a redirect here instead of letting it fall down here to our render template function call and the reason is because of something called the post get redirect pattern now you might not know what that is but most of you have probably seen it before so if you've ever reloaded your browser after submitting a form and then a weird message comes up that says are you sure that you want to reload because the data will be resubmitted or something like that that is because your browser is basically telling you that you're about to run another post request when you reload your page so us redirecting here causes the browser to send a get request and then we don't get that weird message if we try to reload okay so with all of these coding changes saved now let's try this out in our browser and see if we get the functionality that we're hoping for so let's see if our dev server is still running and it says it is so let's reload our profile page and we can see that it filled in our current username and email so that's good and our current profile picture so now let's change some information around so I'll say Cory ms2 khorium Schafer - at gmail. com oops let me put that in there and also I will update my profile picture so on I'll grab this picture here and update okay so we can see that it looks like that worked so it fills in our new username and email here at the top where it's printing those out and also it looks like it changed our profile picture now you'll probably want to go into the in section and make sure all of this looks good to you there also I remember one time I forgot to properly set the instance for one of these forms and instead of actually updating existing objects it was creating a lot of new objects in the background so just to make 100% sure let's go ahead and open the admin site as well and make sure that there's no new users or anything like that so let me make this larger so you all can see if I go into users then we don't have a core EMS user we only have this query ms2 and the email address is updated and this is still the admin user so it did update that user so that is good now let me also check the profiles here so if I go into profiles we no longer have a core ems profile but we have a core EMS to profile here so if I click on that then we can see that let's see if this new image is the one that we uploaded and we can see that it is okay now there is one more thing that

### Resizing Images [16:31]

I want to do here before we end this video so I purposely wanted to update my profile picture to this large photo to show you something else that we can do so I want to show you how you can automatically resize images when you upload them so right now we're just accepting any image that the user uploads but the largest image on our site right now and the CSS is set to like 125 pixels or something like that so there's no use in having a you know huge 4000 pixel image that just gets scaled down to a hundred and 25 pixels it takes up a lot of space on the file system and it also caused your website to run slow because it has to send that large image to the browser every time so for example we can see that this image is really large and it's actually larger than what I think it's showing up here in the browser because it's scaled down a little bit just so it can fit so to resize images when we upload them we're going to use a package called pillow and if you remember we actually already installed pillow when we first use the image field in our profile model because it needs that for the back end so in order to resize this image we're going to override the save method of our profile model so let's open up that model so within our project let's go to our users app and open up our models and here we have our profile model and within our model we're going to override the save method and we can do this simply by saying def save and pass in self as the first parameter there so this save method is the method that gets run after our model is saved it's a method that already exists in our parent class but we're creating our own so that we can add some functionality so first things first I'm actually going to run the save method of our parent class and we can do this with super so if we want to run the save method of our parent class we can say super and then dot save so that parent

### Importing Images [18:33]

classes save method would have been run when we saved an instance of this profile anyways so if we uploaded a large image then that should have saved it but now we're going to grab the image that it's saved and resize it so to do this we're going to need to import that pillow library so within our imports we will come up here and say from PIL and we specifically want to import image from that library so now come back down here in our save method and now let's

### Opening Images [19:05]

open the image for the instance that we're saving now if any of this class stuff is confusing to you then I do have a series on working with classes in Python that you might be interested in and in that series I go over classes and instances and what the self variable is and everything like that so definitely check that out if you want to know more details about the things that we're just briefly discussing here ok so to open the image for this profile instance then we can simply say I'm going to create a variable here called IMG set this equal to image which we imported from the pillow library image dot open and we want to open the self dot image dot path so this will open the image of the current instance and now we're going to

### Resize Images [19:53]

resize that so we want to specify what size that we want our image to be so like I said the max size that we display on the front end of our website is a hundred and twenty-five pixels or around there so let's resize it somewhere closer to that so I think I'll choose around 300 pixels since that's still a small image but it still gives us some flexibility to display larger images in the future if we'd like and if images are larger than this then they'll be sized down so first let's check if this current image is more than 300 pixels so we can say if IMG height is greater than 300 or if the IMG width so if either the height or the width is greater than 300 then we want to resize this so now I'll say output size is equal to and this is going to be a tuple of our max sizes here and now to resize this and

### Save Images [20:53]

save it I can say IMG dot thumbnail and then pass in the output size so that will resize that image and now to save it we can just save it back to the same path in order to overwrite that large image so I'll say image dot or self dot image dot path okay so with that in place then that resized 300 pixel image should be saved to the file path and overwrite the larger image now I should say that I found a lot of different ways to resize images like this when I looked online some of them were a lot more complicated than what I wanted to show you here but there are probably some trade-offs also but really I just wanted to show you an example of what it's like to override the save method of a model and I think that this is a good example but if you are working on a larger project where efficiency is really important then there are some additional ways in which you can do something like this also and there are also some third-party packages out there that you can use that will do resizes and stuff like that for you so if anyone is interested in doing this differently then just leave a comment below and I'll make some suggestions but what we have here should be good for our application that we have so far so now let's test this out so let's open back up our browser so first test our dev server and that's still running now let's open back up our browser and re-upload a large image so I will resize this go back to our profile page and now let's reach up load this large image so I'll upload this and now let's see if this is a large image so I'll open image and new tab and now we can see that the large image that we had before which was this one over here it has now been resized to this 300 pixel image here which will save a ton of space on our file system and also speed up our website now there's a lot more that you can do with this you could write some additional code that deletes old images when a user successfully changes their profile picture but I'm just going to leave those there for now since they're not taking up that much space so now let's close down these two tabs here and also while I'm at it I'm also going to change my username and email back to what they were before so update that and now we have the original username and email okay so there is one

### Display Author Image [23:18]

more thing that I'd like to do in this video and it's going to be really quick now that we have the ability to add a custom user images to our site now let's spice up the home page a bit and display the image of the author beside each post so this information will be in our blogs home dot HTML template because that is where we're listing all of the blog post so let's open up that template so that is within our blog app and templates and then home dot HTML okay and to display the users image I'm going to put in an image tag here with some CSS classes that we added earlier in the series so right below the article tag and right above this div with the class of media body I'm going to put in an image and the source of the image we can set to an attribute here and this is going to be the post dot author dot profile dot image dot URL so I know that's a long one there but the current post the author of profile that author the image of that profile and the URL of that image so a lot to chain on there so that'll be the source of the image but I also want to add a class here so we'll put in a class and we will have this be a rounded circle which is a bootstrap class and then one of my own custom classes here I'm going to put this as article - image and save this so now with that in place let's save everything and open this up in our browser and see if these changes took effect so open up our home page and reload this and now we can see that the author's image is popping up beside their post and I think that's a nice way to kind of spice up the homepage there okay so I think that is going to do it for this video we now have a way for a user to update their profile information and they can also update their profile pictures now in the next video we'll create a page where different users can create posts that will then get added to the home page here but we'll also add a way for them to update and delete the post as well but if anyone has any questions about what we covered in this video then feel free to ask in the comment section below and I'll do my best to answer those and if you enjoy these tutorials and would like to support them then there are some ways you can do that the easiest ways is simply like the video and give it a thumbs up and also it's a huge help to share these videos with anyone who you think would find them useful and if you have the means you can contribute your patreon and there's a link to that page in the description section below be sure to subscribe for future videos and thank you all for watching you
