Login & Register Users - Day 5 - Django Bootcamp

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
and welcome to day five thanks so much for showing up everyone i'm super excited to get into this one because we're gonna be talking about users and user authentication we're gonna do it sort of the hard way it's really easy if you understand the last few days really easy in the sense that we're gonna be pretty much putting together everything that we've already done and not to worry i'll be going step by step so even if you didn't fully get everything from before hopefully this will make it a lot more clear on how you use forms how you use models how you use them all together in a way that actually associates your user so of course our normal agenda not any surprises here probably for those of you who have been with me since day one let's go ahead and just jump in this overview is going to be incredibly short because the value i think is really where the code is and so this is where we're at right we've got a request coming in that request can be kind of two types right if it's an http get um well it could have data in there too but if it's not an http get it has some data that's that little uh graph there a chart there and then http post that goes up either way whatever the request is whether it's an http git or an http post it goes to some url on your page now this is common across all web applications not just django the green stuff is where django comes in so once you either get or post data that goes into a url that url decides which view should actually handle that request that view then also decides whether or not it's going to be using a form so if it is using a form it will validate the form and do all that stuff and once the form is validated the form data will be sent back to the view and the view will then update the database through django models and then of course the view also ends up sending back a response of some kind which has been so much about django templates and rendering out django templates so every web application does roughly this or or should do some version of this as no surprise so the big thing that we want to do is insert this idea of a user and not a user so someone that's actually authenticated with the system like they have a password they actually log in to their version of the application they log in and create a session themselves so that's actually what we want to be doing and something i've alluded to before is every request has a user attached to it this is a batteries included thing that django has so request.user and there's also something that's also built in to every request which is sessions so requests.sessions sessions are really really useful that work in conjunction with the user where the session itself will be persistent throughout the session like every time the user's on there that session can stay on there which is really useful for us because if a user purchase is purchased as a product for example we want to be able to know that yeah they've recently purchased this product and we can leave that in the session itself this will come up a lot more later but for now just know that these two things are attached to every single request that's coming through so they're accessible in a lot of these places and accessible in a lot of this like flow of a request so without further ado let's go ahead and jump into the code i told you it would be a very very quick overview uh because this is so much about actually getting the code down okay so i already have my server running um i actually do want to mention a couple things prior to jumping into the code because i get this a lot that i go way too fast and this is probably true but the django documentation has a lot more things that i won't be covering on authentication now some of these things are just nice to know some of these things are places you'll actually or things that you'll actually use so i do recommend that you go through this and read about it because this has been pretty standard for years so even if you just learn a little bit about it that's going to be okay and you could always do this later like after you implement your own authentication next is the actual settings module itself there's all sorts of configuration you can do here this is something that i probably should have mentioned a long time ago but i mentioned it now because we actually will do some configuration in relation to our login and our session and then the final thing is django all auth now this is a really really impressive tool and package for doing authentication now i think a lot of beginners want to jump to the easiest possible thing and i totally get that django all off definitely makes it really easy to just do user authentication it does social authentication too but the user authentication that it'll do or at least help us with is almost identical to what we're going to be doing here except they implement a few other features that is really nice to use so django auth is something you'll want to check out in the future okay so now let's go ahead and actually look at the code itself so i'm going to go ahead and close out all of these things and i'm going to make a new um view inside of a new application so i'll go ahead and do python manage.py start app and we're going to call this accounts now accounts is fairly arbitrary i don't want to necessarily call it users because i already have a user model inside of django i'm also not going to be creating a user model because django itself has a user model i don't need to do it it's built into django you can for more advanced users you can absolutely change that default django user model but it's just something outside the context of what we really need for this project so what i'm actually going to be focusing on is the view as well as forms so the only reason i have this accounts app is for views and forms and to be situated in some place outside of my other stuff right i actually don't need this to be in accounts but i'm doing it to make it like oh well if they're logging in where would that view naturally sit well you can make an app called off that's an option but you can also just use accounts this is kind of a design pattern that's completely up to you okay so without talking about that too much let's actually uh take a look at actually how to use that user model so uh first and foremost i'm going to go ahead and open up a new terminal window here and then i'll activate my virtual environment source bin slash activate and of course if you're on windows script slash activate and we'll go ahead and go into the python managed shell django manage shell and will actually import the user model now there's a lot of different ways within django that you can get the default user model the way i recommend is going from django.contrib.off we're going to import the get user model function this function is useful if you're using the default django user model or if you're using a custom user model so when in doubt this is a really really good way to grab that user model itself so we're going to go ahead and say user equals to get user model and actually call that function now i can do stuff like user.objects.all and that will actually give me a query set or as in all of the users that are stored in my database okay so that's actually how we're going to go about doing this we're going to be using that default user model and to create users actually want to show you how to do it the raw way before we actually put it into the view itself but to create users there's two ways to do it you can do user.objects.create much like any other actual model you can use user.objects.create and say something like username equals to jmich and email or rather email equals to something at something.com and hit enter okay so i had a little formatting issue with my terminal but um that's something you probably won't see i i made some changes to my terminal so that's why i got that little issue but when i copy and paste it this is actually the command i hit enter it actually creates a user object for me if i try to do that again i get an error right so you need constraint failed so by default built into django you have unique usernames not unique emails just unique usernames so we actually probably want to overcome the email portion so that's something to think about for our form right so right off the bat i'm going to make a little note here in a file called forms.pi so inside accounts i'll go ahead and make forms.pi here now and i want to say check for unique email and username okay so we'll come back to that for sure but now that i've got this i can actually try the other method of creating a user which is user.objects.create underscore user now we can actually pass in a username string an email so abc at abc.com which might be a real email and then we can actually pass in a password so abc123 and hit enter so before i actually didn't set a password with the other user so objects user objects that create user does set that password whereas user.objects.create did not set a password so to actually set a password on a user object we use something called set password so to do this we'll go ahead and say user equal say user.objects.get let's go ahead and say username equals to abc and now i do user.set under underscore password and then whatever i want to set it to so let's say abc1234 which is a terrible password never use that and then we can just call user.save user.set password should actually save it to the database but when in doubt just you user.save so this method actually works anytime so you can do it on this create user right here as you notice it actually sends me back an instance of that user object you can also do it on the model itself right so this right here you can call it after that as well but you can literally chain it together from this and call set password after it uh if you were so inclined but of course this is important for us to actually do registration and authentication so this right here is called an instance method so is save itself an instance method means that it actually happens on an instance of that model right so this right here is creating a model and returning an instance of that model which is basically just one single object from that model itself that of course is python specific but you know i get a lot of questions on what an instance method is that's this right here it's essentially a function inside of a class okay so now we've got some some basics down don't worry if you didn't actually get all of these commands down i definitely have to do them inside of used up high to make sure that this works so let's actually go into the form now i actually want to design the form for this so going back to what i just did which was from django.contrib.auth we're going to go ahead and import the get user model and then i'm going to go ahead and declare user equals to get user model okay so this is how we actually import that user model instead of doing something like from this this actually doesn't work but let's go ahead and say something like from off.models import user right so we don't want to do it this way specifically for the user model every other model we want to do it this way for the user model this is how we this is how it's done and trust me it's it's definitely the best way to do it regardless of how you see it anywhere else i promise you this will be the least amount of frustration and headaches in the future okay so now that we've got that user model i'm going to go ahead and create a form itself so how i actually go about doing this is there's a couple things on how we can think about this we could do a model form much like we did with products right so if we come in here we've got a model form in here or excuse me right here we could do something very similar to that or we could just create standard forms and augment them as we see fit i'm actually going to go the standard forms route and say login form and it's going to be forms.form now the reason for this is i actually don't need much related to the user for this login form there there is things that i will need but i don't need a model form for a login form especially so what i'm going to do here then is i'm going to go ahead and say username equals to forms.char field which is of course a character field and then we'll go ahead and do password equals to forms.char field or character field now of course these are both required so i'll leave them as just like this so i'm not going to say required equals to false because we definitely need both of these so now what i want to do is actually well i want to validate the username itself but i also want to make sure that my form password actually renders out as a password now i did mention before that there's a way to change classes and ids this is also a way to change the rendered input that it is by using an argument called widget so inside a widget we'll do forms dot password input okay so these widgets are plentiful there's a lot of django widgets so just look django form widgets do a google search for that you will see all of the form widgets that are in here and there's a lot of really cool ones so text area is one of them so if you need long content that is definitely a great widget there but anyway so we've got this forms dot password input that of course is going to hide from the user while they're typing now password inputs i i don't know if it needs to be said but it is a really good idea to use a password input on sensitive data so it doesn't have to just be for passwords but it definitely should be for any sorts of sensitive data and you can leave it like this this actually works just fine like that or what we can do is pass in something called attributes so att rs and these are html attributes so stuff like class if you want to add a css class you can add form control if you're using bootstrap this is actually a really easy way to go about doing that and you can also even change the id of it here saying something like user password okay so there's our login form now again i want to actually validate this is a valid username so we'll just go ahead and say define clean username and it takes in self and we get the username equals to self. now let me give us some space here self.cleandata.get and username and now i'm going to go ahead and call a query set for this so it's user.objects.filter username i exact equals to username and then if not qs dot exists don't worry i'll explain this stuff we'll go ahead and raise forms dot validation error and say this is an invalid user okay cool so uh and then finally we'll return the username itself great so this is a way to make sure that whatever username we're using this is going to check that this username is correct now i exact means that if somebody types in this is or this is my user name that's going to be equal to this is my username because actually we want to treat that the same in the database too so capitalization doesn't matter in ixact okay which is kind of ironic because you would think i exact means that it has to be exactly what they put in but that's not how the query actually works okay so now we've got our login form now i think actually you already know enough to go from here but what i actually want to do is a little bit further than this and i want to make sure that this is actually a valid user so how do i actually go about doing that well this is sort of saying that it's a valid user but the actual password may or may not be valid right so this might be the incorrect password from or for this user so we're going to add one more step and that's define clean and it's going to take in self and now clean is actually the last method that's called so it calls each individual username clean right so cleaning the individual one and then the very last one is actually going to be looking for the entire form what this means is i can actually come in here now and use username and password inside of here so clean data get and password okay so this is now saying hey i can actually grab these two items in here on whether or not this is correct data itself right so um this is actually where i can authenticate or verify that this user password is correct right so i can actually do additional form validation here inside of this clean method um and i'm actually going to leave that for another time because what i'm going to be doing is inside of the view itself i'll just go ahead and handle errors inside of the view but in the long run you would probably use clean in addition to clean username or we could just spend a lot of time on clean itself okay so i just wanted to mention those things because you absolutely might have additional form validation um when it comes to something like clean okay so let's actually jump back into view let's implement this login form now so i'll go ahead and come in here and do from dot forms import login form and then we're going to define the login view takes in a request and well as usual we're going to go ahead and say form equals to login form and request dot post or none and if form dot is valid then we will actually go ahead and grab the username equals to form that cleaned data.get username and then we'll go with that same thing here for password okay so um the reason i'm doing it this method as in not implementing this clean method has to do with how i want to handle an invalid password right so maybe i want them to automatically move somewhere else which we'll talk about in just a second but um so let's say we've got a username and password here so now we actually need to authenticate this username and password so the first step is actually doing what's called authentication so from django.contrib.auth we're going to import authenticate so what this does is it will say it will give us a user if this authenticate is valid so it's going to take in the request it's going to grab the username equals to the username and the password equals to the password okay so security things we don't want to print out the password in here right so we we very rarely want to print out this password at all or any sensitive data that for that matter because what that will do is actually stick in to your django logs right it'll stick into the run server log there which is not what we want to have happen that's exposing our users passwords we definitely don't want that so while you're testing of course you could try that out but i would recommend against it in the long run for those print statements of that password maybe there's some way to get around that in the future but as of now there's not okay so authenticate is saying hey is this a valid user and is this their actual password that's pretty much it and if it's not what's going to happen is if user equals to none that's that's what that's what will happen is like this will actually return back none if it's an invalid password then what we can do is actually say request dot session well maybe we can do attempt plus equals to one right so um this is actually an option to add a attempts in here on whether or not this user is actually correct so we would actually do attempt equals to request dot session dot get attempt oops too many there and or zero okay and then you would actually probably do something more like this attempt plus one okay so this is also nice to verify whether or not this user has attempted this too many times this is a really simple way to do that that i'm not going to fully implement that but what's cool about this is it actually attaches to that session as i mentioned before this actually doesn't solve if somebody ends their session or uses a different browser or something like that it's just a really simple way to monitor the attempts they have the other thing about this is you could also then return some sort of redirect so changing them in here and i'm just gonna go ahead and say invalid password all right so this is going to then move them somewhere else right so that's an option for sure the other thing is perhaps what we actually want to do is we're going to go ahead and return the render method of the request and in this case i will keep with form or forms i think i called it let's go ahead and look at the template itself yeah so forms.html and i'll give the context so the form itself as context and then i'll also say invalid user being true okay so that's just a very simple way to add additional hey this is an invalid user now in my forms.html i can handle this invalid user this is also true in other places as well right so now that i think of this concept of additional context that i'm adding to my template for forms.html i can see this and in my session i can also do dot session and invalid user uh being one so one as in one equals to true uh the the reason i'm using one is it's a much smaller footprint but then it's either gonna be one or zero but that's another way to add this into our template so i don't necessarily need to also pass it in as context i can use request.session to do that so let's get rid of that from context don't worry we'll see all this stuff in just a moment uh but then the other option if the user is not equal to none then we can call the login method so log in okay so a key thing here is notice that this is called login and this is called login view now my intuition a long time ago was just to call this login as well which actually overrides this name right so we've got a little issue there so keep it in as login view and you can also just call this as dj login or as django login or something like that just in case you accidentally use login in a different manner okay so logging in is now just saying login and the request and the user so now request.user is going to equal to whoever that user is everywhere on your page until you actually log out whatever that user is or their actual session ends both of which we will cover so once we've got that we can now go ahead and return a redirect to maybe the home page or something like that right and then of course if the form is being is a get call itself we want to render out the form uh just like this right here so we'll go ahead and add in that right there okay so of course i could re-phrase a lot of these things or reorder them and since i'm repeating myself here and here i actually do want to reorder them so i'll go ahead and say if the user is not equal to none then i'll go ahead and add that redirect um otherwise i'll go ahead and do that and then the form will still be rendered okay so just a kind of a reversal of what we were doing so we're not repeating ourselves too much and this right here is now going to be that requested user okay so that is a long way to get our user actually authenticated into our project right it's it's actually not really that big of a deal i hope maybe it is maybe it feels that way uh but it's really cool so we've got a username and password in as secure as a manner as possible in this case and then we've got user equals to authenticate so we actually verify the username and password details here this is where we're saying hey this username and password is correct and if it is correct as in if the user is not equal to none then we can go ahead and log in this user so it's safe to say that user is valid and active like active there is a field that we should probably look at called is active um that itself will also be a factor in here on whether or not this user should authenticate then they log in otherwise they're going to be invalid users really really simple so log out is even more simple so log out is another import we want to have here just like we did with the login view just keep note of that and we'll go ahead and do define log out view takes in a request and in this case we just literally call log out on the request and then we return i don't know a redirect maybe to the login url in this case i'm just calling it slash login so this will redirect back to having the user log out for example obviously but this actually removes the user uh from this request.user this is now gonna be anonymous user okay so add-on user that we can't actually use as in they're not authenticated um okay so those are the login logout views now i'm actually going to do the register form prior to actually implementing this as a url and verifying the url itself so inside of my forms um oops i think no i was just scrolled down in the wrong place okay so um inside of forms again i'm gonna come in here and say class register form okay so forms.form and very similar things we're going to go ahead and use username and password here and then i will come in and use password one and two so password two password one this time i actually want to change the label so i'll go ahead and say label equaling to password you'll see what that renders out in just a little bit and this one i'll just call this confirm password okay and this id will be user confirm password something like that you don't you don't have to change those ids but it's cool to see next we are going to actually have email and this is forms dot email field and i'm going to leave this required so if by default required is true of course you can change that flag to to false if you'd like but i'm going to leave it in as required so much like we did with this clean username what we want to do is the opposite of this okay so the first one is we want to get the username if it does exist this is an invalid username please pick another now in this case i'm actually saying invalid username instead of this user has been taken the reason for that is well we don't want everyone to know that a user name is already taken for example i mean you might want to know people might want to know that but um i think by default from a security standpoint just saying hey this is an invalid username works not only if the username is taken but it's also a username we don't want to have so let's say for instance we want to have a not non-allowed usernames and put in a list of usernames in here something like let's say abc we can also say we might want to start with that one is say something like if if user name in not allowed usernames then we'll go ahead and say the exact same validation error okay again this is only in register which means that in the admin i can still add users with these not allowed usernames uh it's not actually changing the admin at all it's only going to be changing how how the view actually works itself okay so with this same idea of clean username we're also going to want to do the clean email right so very similar to this but in this case it's not going to be the username field it's just the email field so let's change these to email email okay so if it exists this is an invalid email uh please pick another okay or this email has been used this one maybe this email is already in use so um there we go we now have username and email and we haven't actually validated the passwords yet but i will say that this is a very simple way to set up the register form itself okay so let's go ahead and bring this into our view now so i'm going to go ahead and do registered form and we're going to essentially copy this login view because what i'm also going to do is after they register i'm going to authenticate that user and let them just log in so define register view takes in a request and paste this whole thing in here and yet again we're going to go ahead and use that register form we've got password and email so email password and this was actually password one if i recall correctly in the form for password one and then we've got password two here so password two okay so naturally i'm not actually gonna authenticate just yet instead what i'm gonna do is go ahead and say user.objects.create user and this is going to be our username our email and our password right so this is actually the user object itself okay so i don't actually need to authenticate this user so i can get rid of that and you know if there's any exception or any problems that happen with this maybe it's a good idea to put it into a try block and say accept user equals to none and then that way we've got a registration error or maybe just register error and now we've got that error right and again we could do the attempts as well if we'd like um but this actually covers doing a big part of the registration so what i want to do is actually verify several things here first is the login then we will verify the log out and then finally the register view so let's go ahead and bring these in to our urls so inside of bootcamp into urls we're going to go ahead and do from accounts.views we're going to import the login view the log out view and the register view okay so now that we've got those things let's go ahead and bring them in so oops that was a mistake sorry about that let's go ahead and say login and login view okay and then log out view okay and then the final one which will be register and register view cool so now that we've got those let's go ahead and actually take a look on our on our site make sure everything's running got my server running here and of course forms is not defined the simplest thing that i could have imported i did not that's funny okay so from django import forms so we save that and now i have no errors running so far so let's go into a login page itself and i got request object has no attribute post silly mistakes happen all the time that's why we test things that's this right here that should be capitalized i'm assuming that some of you caught that i really hope that you did but even if you didn't we caught it now because django is amazing and tells us exactly what's wrong and where to find it line 27 in login view line 27 request that post okay very simple error very silly easily solved okay so we've got a username and password now granted if your chrome browser or safari or firefox whatever you're using doesn't actually store the password itself then this will be blank in my case it's not blank so i've got this right here and i can log in as a user now i'm already logged in as a user so let's go ahead and log out of that user okay so it logged out and then redirected me sorry to see if it actually did log out by one of the easiest ways is by going into the admin itself another easy way would be to actually use something called login required right so there's a decorator called login required so let's go ahead and search for it so login required decorator django um this is this is how i remember things i don't always remember it off on my head if i've done it over and over i absolutely do remember but if i don't remember i just search it right just do a quick login required and there we go there's our decorator for login required and you're like i don't know what that means yet that's okay but we're going to go ahead and copy this decorator and we'll go to a place that actually absolutely makes sense for a login required which is on products on views that that good old product create view we don't want to have anyone be able to do this we want to only have some people be able to do this so we bring in off decorators login required we come in here and we put in the login required decorator here okay so now whenever we try to go in i don't think i'm logged in but now whenever we try to go to products create and hit enter it's actually trying to redirect me to another url to go ahead and log in right so this url means that yeah you absolutely need to check um that we need to change where that login goes so there's a couple ways on how we could do this the login required decorator allows you to pass in a login url this is fine every once in a while but in my case i actually want to set something in the settings so in settings.hi what i actually want to set is right right underneath the off password validators right here i'm going to go ahead and add in login url equaling to login and then uh login redirect url being equal to slash okay cool so now uh let's go ahead and log out again or actually no i haven't logged in yet so let's go back into products create hit enter now it actually takes me to login to the actual url that's logged in here notice that there is this question mark next this would actually in theory redirect us to that that is something i'm not going to cover at this point but it is kind of cool that there is something like that the reason i'm not covering that at this point has to do with the fact that django has a lot of their own uh login views so authentication views themselves as well as built-in forms okay so if you actually want some of the benefits of the django login related things you totally can use their own views but i wanted to show you how you actually make this happen prior to using you know the login view here this is a class based view which is something we also have not covered so that's something that we are just going to have to um leave for another time but they do have these login views that handle stuff like next uh because we want to handle those things as securely as possible but again that's like we're starting to get too advanced on these login views all together okay so there is another decorator that i wanted to mention and that's because of those products create as well now this is a site that people will log into we don't want everyone to be able to do this so we can also look for something called staff required login decorator django we hit enter here and here's another kind of decorator this is an old version of this so let's not try that one let's go back in here and look for staff requires i got the name wrong staff member required excuse me so staff member required is very similar to the django admin so going back into our products here very similar to the admin we come down here and we do login staff member required just like that and now what it's going to do is force us to log in to the admin and the things as it says in this decorator is user dot is staff equals to true and user dot is active equals to true so those are two things that need to happen for this staff member required to be able to go to products and create okay so in my case this user is that way but if i log out and log in with i think it was jmich and abc123 hopefully that's the password nope invalid password uh abc123 now okay so we're getting an invalid password there so let's go ahead and actually register a new user so again i'll go ahead and say abc12345 and i'm just going to use this as an example with that same password this is yeah that didn't actually work um so you're going well where are the errors here uh well unfortunately i don't have all of the errors showing up right now but hopefully in the future we will have all of those errors uh okay so this is an invalid user so that error at least is showing up now the part of the reason that this error is not showing up it has to do with how we are validating the passwords and all that so let's go ahead and register this user with a better password um and nope still getting errors so let's actually go back in to our view and see what's going on okay so we've got form valid uh it's possible that the actual errors that are happening here are invalid so let's go ahead and bring this up and maybe there's an exception that's happening that i'm not realizing and that's why it's actually just re-rendering the form itself so let's go ahead and resubmit ah yes name user is not fined interesting how silly is that the user is not defined on the view itself silly mistakes happen too often okay so user get user model and we want you to find the user here so user equals to that get user model and there we go that's why we don't always want to put things in try blocks before we test everything out so let's go ahead and refresh this re-resubmit okay cool so now the user should be logged in and if i go to the admin it shows me that i'm authenticated as this user so what i want to show you just one more time is logging out and we see let's go ahead and register and i'll go ahead and do abc cfe or something like that uh and then that same thing email password there we go cool uh so it goes to page not found it goes to the root page that's because we're basically saying that this user is logged in and if we go to products create it it forces us to go to the admin so this person is not authorized to access this page so that's that's what's happening now so it's now saying hey you need to be a staff user to do this if we log in as a staff user and change that user's default permissions and here right so we've got all these users logged in and if we come down here and change what their permissions are they'll be able to see those various views as we put forth okay cool so now we've got several things going on with authentication we now have a way to use these users themselves so in that create view something i actually want to add is the user model itself in the product so let's go ahead and say user equals to models dot foreign key and to use the user model here you're going to be like oh well is it from django.contrib.off import to get user model is that the method we're going to use actually no inside of models and specifically models not anywhere else the way we grab the user model is from django.conf import settings and then we use user equals to settings.off user model and this right here is actually what we'll set on our foreign key you're like what is a foreign key we'll see that in a second hang on and then we'll go ahead and do on delete and this will be models.set null so what this happens is if the user itself the actual user object that's associated to this field is deleted what do we do with these kinds of fields well i said set null i don't actually want to delete the product that's associated so we'll go ahead and say null equals a true here so if i actually wanted to delete all of the associations for this user i would say set or models.cascade and that would actually delete everything that's associated to the soon to be deleted user as well yes that's getting a little bit outside of the context of hopefully basic but the idea here is we absolutely need to have this on delete method in a foreign key and we want to use that user model just like that okay so i made a major change and we actually haven't done this yet we haven't covered making changes in a model now just like we said before when you create models what you need to do is python manage.py make migrations and then python manage.py migrate you hit enter that actually made all of the changes necessary as we see here add field to add field user to product so hey database we're about to change you and then migrate hey database let's change you now and it's doing it with a foreign key so what a foreign key does is actually kind of correlate two tables together uh so it's correlating the product table with the user table so that it's not actually just an id of this user it's it's like much more attached so there's more efficient lookups that we can do related to that hopefully i'll be able to cover these things in more detail all right no let me rephrase that i definitely will be covering these things in more detail next week when we start um you know day six or seven to actually cover how to use these foreign keys in a more robust manner but with that out of the way let's get the server running again and let's go into our view for the product create view so right here okay so we've got our staff member required remember we absolutely need to do that hey remember this oh yeah cool now i can say obj.user equals to the requested user right so the obj.user is of course the object itself it's going to be related to this if i was calling this owner equals to the foreign key of user then you would just change that same thing on the view itself but i just made it simple and called it user so now that now every single time we add a product model or any given product to our product model um this will actually save it as the user itself this doesn't change the admin at all it only changes this view so i get questions all the time how do you customize the admin how do you do all these crazy customizations sometimes it's really good but sometimes it's a lot easier to just create your own view that has a login required for staff members anyways so let's go ahead and actually see this in action now so i'm logged in as cfe let's go to that view here so products create and we'll go ahead and say hello world i own this or i created this and you know some content we had send data okay it looks like it was successful because it's a new form we go into our products our most recent one hey i created this check that out user associated and i also have all of these user these other objects um other options are other users right and this is how it's actually tied together at least in the admin we can now see that it's it's showing me literally every other user so i can actually select those users um which is not the only way to do this i'll just say that you can absolutely just put the user id here and get it in different ways but in this case it's actually associated to it which does all sorts of really cool things one of them being that if that particular user is deleted from my database it just sets this field as null but if i wanted it to delete all of the things that that user has ever been associated to i could use cascade which is a method that's really good for user generated content right so if the user is deleting all of their account how do you actually delete everything that's associated it'd be something like this but in my case i'm using this the staff members only should be the ones that are actually creating or updating these things so that's where that comes in so um that's pretty much it for login and register i'm definitely gonna be doing more things with foreign keys so if that's not incredibly clear at this point let me know and i will say i actually want to leave you with the challenge this weekend this is something i will come back to uh but there's a key an unbelievably glaring weakness and that is how do i actually validate that those are the same passwords how do i validate that you can confirm these things so for the next couple days i want you to figure what that is out and well just let me know let me know in the comments of this video after it posts to youtube and tell me what it is that your solution was because it's actually not that hard and i definitely hinted towards it um in another part so i just really wanted to leave that challenge for the next couple days on how this is handled um so again what what i do want to recap though is the critical thing of this knowing this stuff makes using something like django all off or any third-party package that does authentication for you a lot make a lot more sense because now you understand that there's a lot more things that i could add to this registered view one of them being sending an email directly to this user to have them confirm that email there's a whole set of features that we could build to make that happen or we can actually just use django all off specifically for that that will absolutely do that assuming you have email set up on your page the other part is password forgotten flow as in they forgot their password i have nothing in here that shows you exactly how to do that other than when i mentioned there's that that call that instance method called let's say user object dot set password yeah we can absolutely set the password for any given user this way so there is a way to do this password forgotten but hey might as well use this third party itself to do that yes there are all these social authentication stuff but way before you get there you want to have the email address verification also having check that out multiple email addresses per user a lot of really good stuff with django all auth okay so now i'm going to take some questions um i i think i think this went we i went a lot more in depth in areas that i um intended to just be a little bit more concise but as we're talking about these things i wanted to go into depth and give you a really good look hopefully a really good look in how django handles authentication and potentially how you can handle registration because now the user and the session are attached now i didn't really go into the sessions too much but the idea is as soon as you log out that session will end so this value will go away whatever that value is and it'll create a brand new session for you okay so let's go ahead and jump over the questions let me just queue a few things up here real fast oops wrong one and we've got here we go okay so let's load up some messages here okay so while that's loading i will um you know thanks for watching guys i really appreciate it hopefully got something out of this one to me user authentication is really important but it can get a little dry every once in a while you know what i mean um but it is a critical thing to do well inside of django itself um so yeah let's just keep that in mind um and i'm gonna answer a few questions here only a few minutes of questions if you have a lot of questions then i'll try and actually come back um sometime this weekend to do a live q a that will answer questions in general uh so stay tuned for that uh that all depends on what we end up getting as questions so yeah let me just pull up some of the recent ones you know you planned to do more like 20 minute questions but then we end up getting a lot more um okay so is that valid object model.object.filter count for login um yeah it's actually a very quick way to validate that that query set exists or or not count can you you can use count if you want to get more explicit as to how many items actually exist um so let's see you said for login i'm assuming you mean on the forms itself i'm just gonna go ahead and show others what you mean by this because i think this is a good question okay so let's go ahead and take a look so right here i did if it doesn't exist then we raise that another option we could do in here for this query set there's something called count and if queryset.count equals to one if it's not equal to one or rather instead of saying not we would use that operator if the count is not equal to one then we also might want to do that if for some reason i have multiple like multiple users with the exact same username this i exact becomes even more important there because if you do something like if you have a three or another number there um i exact will take that in in in consideration versus something like i contains uh there's another kind of lookup that you might find somewhere that this will be these will be equivalents then uh which is not what we want we want to actually have the exact thing that's going on there regardless of the capitalization uh so good question thank you for that one let's see all right next one they use email token for login instead of username so you're looking for a one-time password or otp where it actually emails you i think medium does this where it emails you a link that you just click on and it logs you in there are otp packages much like django all auth that you can use for this and if you don't have a username you might actually have to use a custom user model for that as well where there's just no username the username is your email that is definitely something you can do with a lot of the method i showed you here on authentication and i definitely covered this in one of my projects that it goes a lot more in depth to creating all of this custom user off it might have been in the um the tweetmee2 project whereas creating a twitter like application from earlier in 2020 um that one itself i think covers the custom user and and doing different kinds of authentication maybe not the custom user but definitely different kinds of authentication with with a very similar method as what we did here uh good question thank you for that how to verify users by sms okay so i'll give you a just a general overview or um how you could go about doing this first off you will want to have a model that either has a foreign key relationship so models.foreign key or a one-to-one relationship so models.1 to one field um to a user right so you want to have that and with that you would also have a field specifically for their phone number and then you'll use the service something like twilio twilio to actually send the text message so when you send the text message you'll also want to have a unique code that corresponds to that text message that's happening one for the model itself two and then finally of course the actual phone number that's in there so it actually associates all of those things uh and then you just have a view so when they click on the link that you send them with that that custom key it would actually go to a view on your production site and you you'd verify it that way it's a multi-uh multi-step process but actually the verification part the actual process isn't really different with an email either so you can learn how to do that in email which i believe i cover um in the e-commerce course that i have on my website i'm pretty sure i cover the actual custom email verification as well sms isn't any different you just need to use their phone number and email uh or phone number instead of their email thanks for the question there can we use user equals authenticate no you cannot use this at all so um it has to be the request the username and password so you can use an email as a username using a custom user model that's definitely outside the context of this bootcamp but a custom user model will allow you to pass the email in as that username field but of course how would you authenticate a user by saying their username and their email that that fully doesn't make sense you're not actually passing a password some sort of sensitive data in there right so somebody could just guess this and get it right i mean somebody could guess the password too and get it right but that's not something that you would want to do so yeah thanks for the question can i absolutely can i ever elaborate the difference between get user model and settings.auth user model yes so git user model actually gets the user class so it actually gets that user model class um off user model is just a string that points to where the user model class is so let's actually take a look at that settings um off user model let me just pull this up real fast and then i'll show you and here okay so here is the actual setting for off user model this is what you will use in models.pi right so you could actually just use the string dot user so when you're doing a foreign key a mini to minifield or a one to one field you could write this string out and it probably will work but the reason that we call this instead of writing that string out has to do with substituting a custom user model and actually doing that certainly a lot more advanced than what we're doing here but you still want to use best practices even if you're not at that advanced stage yet so that's what you want to use in models.pi when you're associating the user itself so you don't actually i think django gives you an error now if you try to use the user model class itself so yeah hopefully that answers your question that was also a good question thank you for that um why not to use get user model that hopefully i just answered that for you django itself i i think we'll ask for a string specifically so it's really just looking for the database association i think is um sort of the way i think about it at least okay um cool for sponsorship check my email and my instagram dm thank you well thank you for the super chat and i will try to check those things out later today uh yeah okay can i do something on signals yes um i have a lot of different things on signals uh so maybe at some point um i will be able to come back to them um probably not in the boot camp though maybe maybe uh next week next week i still have to plan out exactly what i'm gonna be doing but um i've got i've got nothing so far uh related to signals but i think um i think they are pretty useful so yeah take that with what you will uh huh okay next up so can django take a request keyword args and args via api i'm not sure what you're referring to and that sort of lies out of the context of what we covered today so please keep these questions related to what we're doing today if you want um more general uh q a questions just subscribe and make sure you you hit the notification when i go live for the live q a sessions that's what those are for okay so in final projects are forms model forms and django default off used yesterday you mentioned something that forms and model forms should not be used in final projects i don't remember ever saying that forms and model forms shouldn't be used both django forms and django model forms absolutely can and should be used in your final project it's a really clean way to validate data so perhaps perhaps i misspoke when i said that uh but i will say that um forms are really interesting and really really useful when they're managed by django uh so our final project absolutely will continue along with that perhaps there is some confusion with how to use forms with a authenticated user and that was part of the reason we um we talked about it today so thanks for that um so another question about otp but done by sms yeah you could do it roughly what i said before i mean well i guess i mentioned a third party package but even verifying your email or your sms with those one-time keys once you're trying to verify that account it's it's not any different verifying an account one time or using it as an otp and a one-time password it works identical it's just you want to make sure that your session ends after a certain amount of time which is something you'll want to learn more about on sessions themselves because you don't want to have the session itself open for too long you actually want it to expire after a certain amount of time so that those one-time passwords aren't incredibly insecure right so even if it's like a day or five hours or two hours or 30 minutes it doesn't really matter you definitely want to make sure that your sessions expire cool what's the difference between forms and model forms day four covers this a lot so i would say check out day four um and that way you can really learn more about forms and model forms um you know i think that's that's probably my best recommendation at this point but but basically model forms include a model in the form itself it's just kind of extending standard django forms to also use the fields inside of a model versus hard writing all of the fields thanks for the question which is better uh django built in auth or the django rest framework these can work together so um to say that the built-in auth in django is worse or better than the django rest frameworks authentication i'm assuming that's what you meant by that um they you can use session authentication which is what we just did um in the generous framework thanks for the question you're welcome thank you thanks for coming out and watching how to set custom permissions uh this is a good question the documentation i think covers this really really well so now that you hopefully know how to use uh authentication you will actually be able to see how to set permissions and use those in any given view i think using decorators is really nice for that we already saw the staff member required decorator uh that one checks those permissions so um yeah thanks for the question yo what up let's see here um i'm not sure what you mean by that but yes i i went fast because we're trying i'm trying to cover a lot so i really want to get the baseline django stuff um and i think we're really close to having a lot of the baseline there we still have to do testing which who knows how much we'll be able to actually cover in the gamut that is testing uh but but i do want to do testing and then we'll actually start flushing out the order process of these products we already have the products there we need some images too so those are a few things i'm covering next week thanks for the question how to make validation show um so forms.validationerror if you're using a standard django form rendered inside of a template the validation will absolutely show i had a http 500 error or actually i had a try block exception in there earlier that caused a little bit of a hiccup but that wasn't a validation error that was an import error not not really related to the form just related to not actually um doing all the imports and that that would actually not run an error for the user unless you moved it out of that try block which is what i did and how i figured that part out let's see here cool maybe just a couple more minutes for this um thanks for the other super chat i'm not going to put that up because you're mentioning mentioning sponsors itself there but thank you for that um i will get back to you hopefully soon related to that uh do we need to this is a good one um so do we need to create a new app to handle user authentication no you do not you can use django all off at this point i think that would be a good choice um i definitely need to have its own standalone video for something like that but if you create a new app it just keeps things self-contained that's why i do it when in doubt for your apps just make it as self-contained as it possibly can be and then you'll be you'll be in good shape so um if you're doing custom auth like i did then yes you probably should custom off in the sense of the flow the authentication flow is custom the actual authentication and the user model itself all of that was the built-in stuff you could use the the built-in django uh views as well um there there's a number of examples online on how to do that and i'm sure i cover exactly those things in one of my projects maybe one of you guys know about it uh cool thanks for the question what about google and facebook authentication yeah so the django wall auth actually gives you some documentation on this it's it's actually a quite a bit more complicated because they use something called oauth 2 which requires you to have callbacks and ways to handle um so if you if you've logged in with google for example what happens is it actually brings you to a google web page usually it's in like a smaller pop-up or something like that and then on google you actually log in select the account that you want to use and then that actually sends a callback token to your your actual application so so that that extra step makes it a little bit harder to to set up um so yeah django all off makes all of that much much easier although it still can get a little complicated uh so that that's definitely outside the context of this bootstrap or this bootcamp so maybe in the future we can we can do a boot camp on it or i could just make more videos related to django olof for this authentication stuff i definitely have a whole on series of django olof on cfe.sh that's my website right there so cfu.sh just the about the youtube that's um that's how you can actually go about uh learning about oauth i think i just cover i might cover both google and facebook but there's a number of steps there that that just takes a while um yeah so i briefly mentioned this when we covered models so blank equaling to true means that django itself and specifically in the forms uh it's not required so when you're using that field it will allow blank values to be in there um it's specifically for django it doesn't actually have to do with the database at all null equals a true has to do with the database and that means that the database field itself can be null or completely empty as in no string value just nothing in there uh that's that's the option for that okay so let's see here um okay i think that we're getting um a number of questions yeah so i just answered this one um and this was covered in the models part for sure so maybe go back and watch that one over again uh all right okay well it looks like we're getting um a number of things that are outside the context of this i know about login logout search and crud and django can i say that i am developer um sure go ahead you can say whatever you want to be uh whatever you want once right like you can call yourself whatever um now to be an actual paid developer is a whole different story so to get there just start freelancing and then you can definitely say that you're a developer and other people will be like well that's cool silly question okay so we uh need to discuss multiple query sets we definitely need to discuss query sets more this will definitely be something i come out with in the future uh so yeah okay guys so that's going to do it for the questions i went a little bit longer on the questions today mainly because the code part took a little bit longer than i initially anticipated but hey hopefully you got a lot out of this one thanks so much for watching and have a good weekend definitely check out that challenge that i left you at the end of the coding part i really hope that you guys can solve that uh i will uh depending on on the feedback from you i may or may not actually solve it for you i might just leave it open-ended because it's one of those challenges that i think you can do now all right so thanks again for watching and i'll see you guys
Info
Channel: CodingEntrepreneurs
Views: 24,073
Rating: 4.9476638 out of 5
Keywords: django, django-bootcamp, ecommerce, django3.1, python 3, web application development, python web apps, djangocfebootcamp2020oc, live coding, live stream
Id: x8yxM7rCvEc
Channel Id: undefined
Length: 74min 16sec (4456 seconds)
Published: Fri Oct 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.