# Python Flask Tutorial: Full-Featured Web App Part 7 - User Account and Profile Picture

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

- **Канал:** Corey Schafer
- **YouTube:** https://www.youtube.com/watch?v=803Ei2Sq-Zs
- **Дата:** 04.05.2018
- **Длительность:** 42:14
- **Просмотры:** 262,803

## Описание

In this Python Flask Tutorial, we will be finishing our user account page so that a user can update their information. We will also be adding the ability for a user to upload a profile picture. We will learn how we can resize this image so that it doesn't take up much room on our server. Let's get started...

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

The snippets used in this video can be found here:
https://github.com/CoreyMSchafer/code_snippets/tree/master/Python/Flask_Blog/snippets

The default profile picture I am using can be found here (Unsplash License):
https://goo.gl/86mXKx


✅ 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 - http://coreyms.com/
My Second Channel - https://www.youtube.com/c/coreymschafer
Facebook - https://www.facebook.com/CoreyMSchafer
Twitter - https://twitter.com/CoreyMSchafer
Instagram - https://www.instagram.com/coreymschafer/

#Python #Flask

## Содержание

### [0:00](https://www.youtube.com/watch?v=803Ei2Sq-Zs) Intro

hey there how's it going everybody in this video we'll be finishing our user account page where our users can update their information and we'll also add the ability to upload a profile picture as well so let's go ahead and get started so first of all let's update the template for our account page this will be the page where the user can update their information and also upload a picture so I have the account template open here and now I'm going to grab a

### [0:24](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=24s) Getting the HTML

snippet of HTML from my snippets folder because it would be a lot to watch me type all of this in and the code for these snippets will be in the description section below if you are following along and want to grab that so within my snippets folder here I'm gonna grab this code from account HTML and now back in our project in our account template I'm going to paste this within the content block so I'll replace the h1 heading that we have there for now and now I will make sure that this is indented correctly and this HTML here is just a short little layout that has some bootstrap classes to make things look a little nicer plus some styles from the main CSS file that we added earlier into our static folder which is referenced in our layout template so we can see that in the snippet that I pasted in here we have an image for the users image and right now that's hard-coded to user image JPEG we'll change that in just a second we also have this h2 heading here with the users username and also this paragraph tag here with the users email so for right now let's change the username and the email to be the current users username and email address and we've seen how to do this before we can use these double curly braces here and now we can say current underscore user dot username and now we want to also put in their email address so we'll place this filler email there with the current user email now like I said we also have

### [2:00](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=120s) Default Profile Picture

an image here for the user's profile picture and right now the source for this picture is just hard coded in but we want this to be set to the users image if they've uploaded one and to display a default image if they haven't uploaded a picture yet so if we remember back in our database video we set the users image file field to be equal to default dot jpg by default so we need to actually create this default image so that we can display that for now and we can use any image here but I have one that I like that I'm going to use for now so I have a folder on my desktop here called profile underscore pics and if I open this up we can see that we have a default jpg image here that's kind of an anonymous user and also put a link for this image in the description section below if you'd like to use this as well so I'm going to go back here to my desktop and now I'm going to move this profile pics folder into my project static directory so that we can use the URL for function to grab that image so I am within my static folder here in this other Finder window you can see right now we just have this main dot CSS which we've added earlier in the series and now I'm just going to move that profile pics folder into that static directory okay so once we've copied that over now let's update the hard-coded image source within our account template to be equal to the user's image and again that'll be default jpg if they haven't uploaded an image yet so I'm actually going to set this and our routes and pass it into our template so first let's open up our routes dot PI file and let's go down to our account route here at the bottom and now let's set the image file that we want to pass to that template so I will say image file is equal to and we're going to have all of these user images located in the same place so this is going to be URL four and we put that in the static directory and within the static directory we can say that the file name is equal to and that was in a profile pics directory and now let's concatenate the current users image onto the end of this Phi now you could use an F string here as well but I'm just going to use the plus sign for concatenation so now I'll say current user dot image file and if we remember image file if I open up my models dot py in the user model image file was the name of that column where we're storing that image and like I said before we have a default set the default dot JPEG so back to our routes so we now

### [4:53](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=293s) Profile Picture Image

have an image file variable here that is set to the URL for our static directory and within our static directory profile pics and then the users image file okay so now let's pass that image file into our account template so just like we've seen before when we do our render template we can just pass additional arguments into here so I'm just going to call this the same thing as our variable so I'll say image file is equal to image file and now within our account template if I open that back up we can now use that image file as the source instead of the filler value that we currently have so I'm going to get rid of that filler value and just put in our double curly braces here and we want to use that image file that we passed in to this template so now if we save all of the

### [5:44](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=344s) User Account Page

files that we just changed then we should have a basic account page for our user so let's run this in our browser and see what we get so I'll pull up my terminal here and clear this out and then I will run our application by doing Python run PI so if I run that we can see that we don't get any errors and our web server is running and I will pull up our application here and reload this okay so now I am already logged in here so if you're not logged in then you'll have to log in order to get to the account page now if I click on account then we can see that we have a basic account information page here where it's showing our default image also our user name and our email now within this page we'll also want to be able to update our user name and email address and also upload a custom profile picture as well so we need to create four for that and so let's open up our application and open up our forms dot py file so I will open that up so now we want a form to update our account information and this is going to be

### [6:53](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=413s) Update Account Form

similar to our register form because it's going to allow us to update our username and email address so I'm just going to copy our registration form as a starting point so I will copy those custom validations as well so I'll copy that come down here to the bottom and paste that in and now I'll change this name here from registration form to update account form and we are gonna leave the username and email fields as they are but we don't need the password or confirm password fields so we will remove those we are going to have the ability to update our password and we'll see that later in the video but it's not going to be through this form it's gonna be through a reset link and an email and we're also going to add a field here to update our profile picture but for now let's just get this working with the username and email and come back to the profile picture in just a second ok so now instead of this submit button saying sign up let's change this to be update so I will save that and for our username

### [8:00](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=480s) Username and Email Validation

and email validations these are going to stay pretty similar so for the registration form they were just checking whether the username or email already exists and would throw a validation error if those were already taken but we have to realize that our user could submit this form without changing either their user name or email and the way that this and that should still be valid but the way that this is set up right now is that it will query the database and find their current username and email in the database and see that value is taken and we'll throw a validation error so we only want to run these validation checks if the data they submit is different than their current username or email so let's import the current user from flask login so that we can use that to make this check so up here at our imports I will import flask login so I'll say from flask underscore login import and we want to import that current underscore user so I will copy that go back down to our update account form and now we can say that we only want to do these validation checks if the username or email that they enter is different than their current username or email address so I will come up here to the top and for this username validation I'll say if username dot data is not equal to the current user dot username then we can run these validation checks if it is equal to the current username and then we're just not going to validate it so now I'll copy this conditional here and do the same thing for our email so I'll say if email dot data is not equal to current user dot email then indent everything underneath that okay so now

### [9:52](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=592s) Importing Forms

let's import this form that we've created into our routes and then from there we can pass it into our account template so I'm going to open up our routes here and at the top we want to include this in the forms that were importing so right after our registration and login forms we will also import this update account form and copy that and then down in our account route we can create an instance of that form and we've seen this before with the registration and login routes and now we can pass this form into our template so where we are rendering the template here at the end I also say form is equal to form and if we want we can break these lines up to be you know pepp eight compliant in these videos I make the text so large that it's easy for it to run off to the right of the screen but I will take that one on to the next line there so we can see all of that okay so we'll add our form validation

### [10:50](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=650s) Reusing Forms

logic here in this route in just a second but first let's just get this displaying in our template so like I said this form is similar to our registration form but with fewer fields so I'm going to open up our register template and grab the code that we use for that so that we can reuse it and so within the registration template I'm just going to grab this entire div of this content section and that wraps our form and I'm just going to copy that entire thing so I will copy that and then within our account template within my snippets here I have a comment in the HTML for where to drop this form so I'm just going to paste that in on this line right here so go up to the top here and save that okay now this is similar to our registration form but it's not exactly the same so we're going to keep the username and the email fields but we want to get rid of the password and the confirm password fields and we're just going to get rid of the entire div that surrounds those so these divs of form groups I'm going to delete both of those for the password and confirm password fields so let's take those out and lastly I'm also going to if I go to the top here we can see that we have a legend I'm going to change this legend from join today and I'm gonna change this over to say account info now we've already gone over what these different form elements do when we created the register and login routes in the third video of this series so I'm not going to go over those again in this video like I said this is pretty much like our register or form with some stuff taken out okay so now let's see how this looks in the browser and make sure that we changed everything correctly so I'm going to save all of the files that we changed and now let's pull this up so it looks like we need to restart our flask server here so I'll do a Python run PI and now pull this up in the browser and reload our account page and actually now that I'm looking at this I don't think that I like the border around this section here around our form and that is that div of content section so I'm going to remove that so I'm going to go back to our account dot HTML template and I'm only going to use the form and I'm going to get rid of this div of this content section so I'm going to get rid of that and right after week close our form I will get rid of that closing div for that and save it okay so now let me reload this in the browser and see how this looks so I will reload this and now we can see that border around that section is gone and I like that a little bit better now none of

### [13:37](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=817s) Adding Allow Messages

this currently does anything when we submit this form but we'll get that set up right now and another thing that jumps out to me with what we have here is that it would be nice if our form already had our username and email filled in for us when we navigated to this page so let's go add that now so I will pull up our project and I will go to our routes dot PI file and first we need to add our allowed messages because we're going to be posting this form back to this route and that is something that is easy to forget when you add new routes with forms so I'm just going to grab that methods section from our login route and paste that down here in our account route so we're allowing get and post requests and now we want to add in a conditional for if our form is valid when submitted so we're going to say if form dot validate on submit and that's actually a method so we need to put parentheses in there and now if our form

### [14:37](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=877s) Updating User Variables

is valid then we can update our current username and email and one good thing about SQL alchemy is that it makes this really easy so we can simply change the values of our current user variable and then commit those so we can come in here and just say current user dot username is equal to and it'll be equal to form dot username dot data which is what they are going to enter into the username field in that form and now we can also set the email by doing the same thing so we can say current user name dot email and form email data and now all we need to do is submit that so we can say DB dot session dot commit so if I save this now let's also add a flash message that tells the user that their account has been updated so I'll say flash and we'll pass in a message here that says your account has been updated and then also let's pass in a category which is going to be our bootstrap class and so we'll pass in a category of success for that and now let's redirect them back to the account page so I'll say return redirect and that is going to be URL four and we want the URL for the account page and you do want to do a redirect here

### [15:59](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=959s) Post Get Redirect

instead of letting it fall down to the render template line and the reason is because of something called the post get redirect pattern and you might not know what that is but most of you have probably seen it before so if you've ever really reloaded your browser after submitting a form and you see a weird message that comes up that says something like are you sure you want to reload data will be resubmitted or something like that is because your browser is basically telling you that you're about to run a another post request when you reload your page so us redirecting causes the browser to send a get request and then we don't get that okay so that should take care of updating our users username and email but I also said that it would be nice if our forum was already populated with the current users username and email as soon as we go to the account page so to do this we can add on to our conditional and we can simply say so here we're saying if form not validate on submit and then we can add to this and say L if request dot method is equal to a get request then we can populate those form fields with our current users data so I can say form dot user name dot data is equal to current user dot user name and now also do the same for the email so I'll just copy that and paste it in there and now change both of those to be email so those changes should populate

### [17:31](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=1051s) Testing

our form with the current users data okay so now that we have those changes in place let's make sure all of that works so first let's pull up the site and create a second user so that we can make sure the validation that we put in place is working so I'm going to make sure that our server is still running here it looks like we need to restart that so I'll do a Python run PI and go back to our website and now let's log out and create a second user here so that we can make sure that our validation is working so the user name I'll just type in as test user this will be test user at demo comm and then paste in a password of testing there and sign up so now we have a second user in our system that is set to test user now I'm going to log in with the first account that I first created and then I will try to update my account so first I'll log in and now I'll go to my account page and we can see that the form is already populated with the current users data so we have our current username and our current email address so now let me try to update my username and email using the values of the other account that we just created so I will try to set my username to test user and I will set the email address to test user at demo comm so if we update this then we can see that both of those fields came back as being invalid saying that username has already taken and that email is already taken so that's good but if we instead change these to something like test user 1-2-3 and test user 1-2-3 at demo com if I update now then we can see that the account was successfully updated and those values for our username and email are also changed here in the heading now it looks like my flashed message here I should have started that with a capital letter there so I must have missed that let me go and change that which is just right here so I'll change that back save it open up our website again so now let me change these values back to what they were before and this shouldn't be a problem because those old values will no longer exist in the database because they've been updated to these new values so I can set these back to what they were so Cory M s and then Cory M Schafer at gmail. com so we can update that okay so we can see

### [20:03](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=1203s) Changing Profile Picture

that changes back fine okay awesome so we've got a pretty good account page here where users can update their information so now let's focus on getting this set up so that we can change the profile picture now to do this we're going to need to add a new field to our form that is an input type of file so let's open up our project and go back to our forms and at the top of this module we're going to import a couple of things from flask WTF so this is going to be so right under flask WTF here I'm going to say from flask WTF dot file and from there we want to import they file field and that needs to be uppercase there so file field and also

### [20:49](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=1249s) File Field

file allowed so this file field is going to be the type of field that this is and this file aloud is going to be just like a validator where we can say what kind of files we want to allow uploaded and in this case we can restrict it to as since we're uploading images to something like jpg and PNG so let's go down to the update account form and see what this looks like so right above our submit I'm going to add in another field here and we will just call this picture and we'll set this equal to file field and now just like our other fields we can pass in the label for this field so I will say is update profile picture and now we can pass in our validators so we'll do validators is equal to a list of validators but this is only going to be equal to 1 this will be file allowed and now the arguments that we're going to pass in here is a list of allowed files so for this example we're just going to accept JPEG images and PNG images if you want to add more file extensions on there then you can if you want but this is just we're going what we're going to do for this example and now we have to actually make sure that this field is going to be rendered in our template so we've updated the form and now we need to pull up our account template here to make sure that this gets added now at the bottom of our form here right above our submit button I'll put this picture field and this would be a little different than our other fields so I'm not going to copy and paste the entire div for that section but I will grab certain parts so I'll grab the opening div here and also the label and then I'll paste in a new form group here and then close out that div and then we want this to be form picture dot label and we won't give this any class that's just going to be empty there and now underneath here we will add the field itself so this will be form dot picture and we do want to give this a class so we'll say class is equal to and we'll set this equal to the bootstrap class of form control - file and save that now if we get any validation errors back then these errors are a bit different for this file form field so I'll just use a simple span to spit out those errors so inside of our div here I will put in a conditional with our curly braces and percent signs and say if form dot picture dot errors and loop over the over these just like we did our other errors and then I'll copy this end if section here and paste that in and now we want to loop through and print out those errors if there are any so I'm going to grab this for loop here since this is similar to what we're going to be printing out so I will paste that in and correct that indentation now instead this isn't for our email this is for our picture so we'll say form dot picture airs so for error in form picture errors then we want to print this error here and we're also going to want to put in a break after that span so that we can get some spacing between those and all so let's do a class here of text - danger that'll just make sure that those errors are outlined in red text now we didn't have to do that in our other forms because they were wrapped in this invalid feedback div but this is a different kind of field this is a file field so we had to do this a little bit differently ok and one thing that I forget to do sometimes that always throws me off is to add a special encoding type to our form and we have to do this in order for our form to pass our image data properly so at the top of the form here in the HTML where we have the method of post and the action we need to also add an encoding type so I'll say E and C type is equal to and within double quotes there this is going to be multi-part ford slash form - data so again be sure that you get that because sometimes I forget to put that in and the errors that you get aren't entirely obvious if you forget to put that in and it's something that's tripped me up in the past ok so now

### [25:26](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=1526s) Testing the App

let's see if we got everything right now so far so let's pull up our site and the browser so it looks like our web server is still running so that's good and now I will reload our account page and we can see at the bottom here that we have an input to choose a new profile picture now we don't have the logic in place to save this image yet but our validation should already work if we try to upload something that isn't a JPEG or PNG so let me try to upload a text file or something like that so I think I have a text file on my desktop so on my desktop here I'm going to try to upload test dot txt so let's open that so when I choose that you can see that it gives us the name of the file that it's going to upload there so now if we submit this then we got an error back here and it said file does not have an approved extension and then gives the extensions here jpg and PNG now like I've said a couple of times now if you get to this point and your form doesn't seem like it's doing anything then definitely double-check that you have that encoding type set in the HTML because I forgot that before and it's not really obvious where the problem is and also it's not really mentioned much in the flash doc you patience oh it took me a while to find out whenever I ran into that okay so now let's add the logic to our route to actually save this profile picture for our user so if we go to our routes I'll open up my project here and go to the routes dot py file then within our validate on submit conditional let's add another conditional to the top of this to see if there is any picture data because that's not a required field so we're gonna have to make this check so we can say if form dot picture dot data then we want to do something with that picture data and now within this

### [27:19](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=1639s) Saving the User Profile Picture

conditional I want to set the user's profile picture now the code is logically its own little section of code so it would be nice just to turn this into a different function so I'm going to create a new function above our account route here and I'll just call this save underscore picture and we'll take the picture data as an argument here so I'll accept an argument that is form picture and save that and now inside of that safe picture function will put the logic for saving the users uploaded image to our file system so first we don't really want to keep the name of the file that they uploaded because it might collide with the name of an image that's already in our folder so it would be nice to just randomize the name of this image with something like a random hex so one module that I like to use to create a random hex is one that we saw earlier in the series when we created our secret key and that is the secrets module so I'm gonna go to the top here and import the secrets module so I'll say import secrets and then go back down to our save picture function and now within the safe picture function I'll create a random hex that will be the base of our file name so I'll say I'll call this random underscore hex and set this equal to secrets dot token underscore hex and we'll pass in eight bytes there and now we also want to be sure that we're saving this file with the same extension as it was uploaded so if they uploaded a PNG then it'll be a PNG and if it's a JPEG then it'll be a JPEG and in order to grab the file extension from the file that they uploaded we can use the OS module so I'm going to import that as well so at the top here I will import OS now back down in our save picture function and now we can use the OS path split ext function to get this extension and that function returns two values it returns the file name without the extension and then it returns the extension itself so to grab both of those values we can say F name and comma F ext is equal to AU s dot path dot split ext and then we want to pass in the file name of the picture that they uploaded so we'll say form picture dot file name now this form picture here is going to be the data from the field that the user submits and if it's a file then it does have this file name attribute there so we can use that now we're actually not going to use this F name variable at all we're only going to use the extension now one common thing that people do with in Python when they just want to throw away a variable name is to use an underscore so let's do that now if you don't use an underscore then whatever your editor you're using it might gripe about you having a variable that is unused in your application okay so now let's combine the random hex with the file extension in order to get the file name of the image that we're going to save so to do this I'll just create a new variable here called picture underscore F in for a file name and I will set this equal to the random hex plus the file extension so it'll just concatenate both of those together and now we need to get the full path to where this image will be saved so that Python knows where we're saving this and to do this we're going to use an attribute that we haven't seen yet and that is the - path attribute of our app and that will give the route path of our application all the way up to our package directory so if we want to save this image into our profile pics within our static folder then we can create a variable here called picture path and we will do an OS path dot join and we will join the app dot route path that with static ford slash profile underscore pics and then we will also join that with the picture file named variable that we just created and we're actually going to use that variable so those can't be within strings okay so let's look at this full line again so we have picture path equal to OS path join we are joining that with the app dot root path which is going to give us the full path all the way up to our package directory and we're going to join that with our static folder and profile pics within the static folder and then join that with our picture file name and using that OS path dot join will make sure that all of that gets concatenated correctly into one long path now if you're not very familiar with what the OS module can do then I do have a separate video on that and that goes into more detail about that module if anyone is interested ok and then we can

### [32:39](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=1959s) Updating the User Profile Picture

actually save that image by using this form picture variable again and we can say form picture dot save and now where we want to save this so we can save this at the picture path that we just created so now at this point we've actually saved that picture to the file system but the users image in the database is still set to the default image so we need to update that but since everything and this function is just about saving our image so far let's not put that logic in here instead let's just return the pictures filename that we created so that the user can use that value outside of this function so now I'll just return this picture file name so return picture underscore F in and now back in the conditional that we were writing before we created that function now we can use that function that we just created to save our picture and give us back the file name so we can say picture underscore file is equal to save picture and that's the function that we just created and now we can pass in that form data so form dot picture dot data and I will go ahead and save that and now we can set the current users image to that picture file just like we did with the username and email so I'll copy that line and paste that in here and now we're going to set the current user dot picture oh and actually I forgot that's not picture that is let's see current user image file is what we called that in our models so we need to set the current user dot image file and we want to set that equal to the picture file that was returned from that save picture function so I'll paste that in there okay so now let's save

### [34:32](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=2072s) Testing the Changes

everything and test this out because that was a lot that we just changed so we want to make sure that nothing is broken so let's open up our terminal and we'll probably have to restart our server here and we do so I will run our server and then open up our website and now I am here in my account page so I'm going to try to update my profile picture so I'm gonna actually use a real image here so I will set this equal to this avatar dot PNG on my desktop so I'll open that and now we can see that we're going to update our profile picture to avatar dot PNG so I will update that and we can see that seemed to work it put our new picture here in our account page ok so that is great that works so far and also let me reload the page here to make sure that is still there okay and it is now there is one more thing that I want to do here before we end this video 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 is just set in CSS to 125 pixels so there would be no use in having a 4,000 pixel image that just gets scaled down to 125 pixels it takes up a lot of space on the file system and will also cause your website to run slow because it has to send that large image to the browser every time so for example I have a large image of my dog as a puppy on my desktop and if I upload that as my profile picture then I'll choose file here and we can see that this is large jpg so I will open that and now I'll update this as my profile picture and we can see that worked now this new image that we uploaded actually looks small but that's just scaled down in CSS if I actually right-click on this and go to open image and new tab and then look at this image in the new tab then we can see that this image is actually pretty large so let's resize these large images before they actually get saved to the file system and to do this I'm going to be using a package called pillow and I have a separate video on this package that some of you may have seen before where I go into a little more in-depth how to work with pictures but in this video we'll just be using this to simply resize the image to 125 pixels so first

### [36:59](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=2219s) Installing Pillow

we need to install that package and we can do that with pip so I will open back up my command line here and shut down our webserver and clear this page and we can do this with a pip install and this is pillow with a capital P there so pip install pillow and once that is installed we can import that into our routes so I will bring back up our application here and go to the top of our page and right below our secrets here I'll say from PIL and this was installed when we installed that pillow package then we can say import we want to import the image class from that library so now let's go back to our save picture function down here towards the bottom right here and now within this function we want to resize this image before we save it so right above our picture dot save we can resize this so to do this I can set an output underscore size and I'll set this to a tuple of the size that we want and I'm just going to set this to 125 and then we can create a new image so I'll say I is equal to image dot open and we want to open the image that we passed in to the function so form dot picture and now we want to resize this and we'll say image dot thumbnail and we'll set that equal to the output size and now we can save this image instead of saving the form picture that we passed in so instead of doing form picture dot Save we're going to do I dot save because I is the new image that we created from that form picture so like I said that is a pretty simple example of an image resizing and if you'd like to see more of what you can do with images then you can check out the video I did on that pillow package but now we should be able to save this and see that our large picture now gets resized on our file system so I saved everything there now let's rerun our server so I will do a Python run pi and open our website again close down that old image and now for the update profile picture I'll just update that with that large JPEG image again so now let's submit this form and it should resubmit that picture again but this time it should be resized so now if I right click on this and go to open image and new tab and look at this image then we can see it's no longer that very large image that we had before this is scaled down to 125 by 125 pixels and doing that is going to save a ton of

### [39:52](https://www.youtube.com/watch?v=803Ei2Sq-Zs&t=2392s) Viewing Images

space on our file system and also speed up our website and we can view these images within our file system so if I was to go back to our static directory here that I had opened up before if we go into that profile pics directory within our static folder then we can see that we have these images that we uploaded to our site now we have two here that are of my dog and one of these should be large and one of them should be small so I'll preview both of these we can see that is a large one and if I go over we can see that is just a small one so I'll close those out and if I was to check the size of these images so I'm on this one I'll go right click and go and get info and it looks like this one here is 2. 7 megabytes and if I do a get info on this one is 8 kilobytes so the difference is huge and lastly you can see that the images that we uploaded here do have a random hex token as the file name for the image and the correct extension so these are JPEGs and this one here is a PNG and we can also see that our older profile pictures are still here that aren't active anymore and if you'd like you could also write some additional code to clean those up and delete those when a user successfully changes their profile picture but I'm just going to leave those there for the time being since they're not taking up that much space 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 can also update their profile pictures and in the next video we'll create a page where different users can create posts that get added to the home page and we'll also show how to update and delete those posts from within the website so 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 several ways you can do that the easiest ways to 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 through 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

---
*Источник: https://ekstraktznaniy.ru/video/12319*