So now we've understood a little bit about the user object and how we do things in templates, and how we get at the URLs for login and logout, and then how we redirect back to ourselves. Let's talk a little bit about the login page itself. So the login page is something that's provided by Django, but it needs a template and so what happens is we get to control the template. We're going to go to this URL, the code behind the view is the code that looks up the password, the codes that gives you errors. That's all taken care of, all the views are taken care of and what we get to do is we get to describe a template that controls our look and feel. So we can have a simple login thing or a pretty login thing and we can have links to the rest of our application, and so we want control over our login page so it looks like it comes from our application rather than having it looked like it came from Django. So I'm not going to go through in much detail about how this works. You have to create a template that can be accessed as registration/login.html and remember that no matter which application in Django project you're working in, those names are global. So for example, this name right here, registration/login.html. The fact that it's in my home application doesn't matter and that's why we have this extra slash in here. So just because it's in the home application doesn't mean it has to be the home and the registration don't have to be the same in this particular case. So this is a template that if they just do a render. So in their view, in the login view that somewhere deep in Django, they're just going to do a render to registration/login.html. You have this somewhere in some application because the templates are global, it's going to find your template and put that in. So within this template, there's a few rules that you've got to follow. They're going to send end-use, they're going to send some errors and there's errors, if the form has errors, you have to have some output that deals with that. If next, that's actually that next equals parameter. So if next is there and you come into this log, and this one's a little bit weird. If you have a going forward page, that means you came from a page and you're going to go back to a page. If the authentication happens, that means you've been logged in, you went to the page, the page kicked you back because it's protected by more than just logged in user. So this little bit right here that's a little bit subtle. If you're not logged in, that's the normal case. Please log in to see the site and then we basically create a simple form, we're going to post to the login URL that just looks up the login URL and we've got this context variable called form and we can print that out. That form has the key, that form has all of the input stuff in it and we're going to talk about forms coming up soon. So that's what generates this form here, generates all this stuff right here and so there could be a bunch of things in there, but the form is created as a variable created by the view that has all the input names and areas, etc, that it wants. So we didn't have to actually construct the form. We do have to submit, put the login button, we could put a cancel button, and we do have to pass the next back as a hidden field. Now, a hidden form field is just like a text field, except that it doesn't show up here. So that's in there and if you were to view source, you would see that. So that's after you submit this form, it needs to know where we're going to go next. So then if you're successfully logged in, it's going to log you in, say, yay and then it's going to redirect to whatever that next value is and that's our way of, it's going to give us the next value inside this template but we have to give it back to the view when we post back to into the view. So like I mentioned, there's a whole bunch of data that we can get. There is this user variable and that user variable has their full name, their email, and very importantly, the primary key of the logged-in user. But these things are only defined if user is authenticated is true. You can access this user data in Python, it's in a little different spot. It's in the request. So I just changed the name of request to req, that's just a variable name you pick. Generally, always write it as request or req. So the user information that is pretty much the same as what's in the template tag. Well, template context, user, user is authenticated, their username, their email. I could've had req.user.id if I wanted here and otherwise it's not logged in and then I just throw this back as a simple HTTP response. This isn't all that useful. It's just showing you how to get your hands on those values if you're in Python. So sometimes you're in Python, sometimes you're in templates, quite commonly you're in templates. So I've been talking about a view that requires a logged in user. So again, imagine something where you're reading your messages on a online system and you bookmark the message reading URL, and then you shut your browser down which logs you out of the system. Then you click on that bookmark straight to the messages, my inbox or whatever, and then inbox looks at you and says, "You're not logged in. So I'm going to send you to the login. You finish logging in and then you come back." That's what the next equals does. Now there's a couple of ways in the views to write that feature that basically says, "This view is fine, but only fine for logged in users." So let's take a look. So one of them is checking to see if the user is authenticated. So I have two views in here. One is, I'm going to protect it manually and that's so you can see how it works, but it's really not the right way to do it. You can do it this way, but there's always a better way in Django. So here we have a class based view and we ask, is the user authenticated? If the user is authenticated, we just do whatever. Now, there might be a whole bunch of stuff in here, but I'm just going to render the thing so that that's a view. So I'm protecting this particular ManualProtect view. But if you're authenticated, you can see it. It doesn't do anything in particular other than dump a bunch of data out. If you're not authenticated, then I'm going to construct a login URL by calling reverse. Say, lookup the URL for login, add a question mark, and then add the request path, which means wherever we're at, come back to it. So that's going to put next equals. Then instead of returning a render, we return a redirect and say, "Go to the login URL." So the way this is going to work is, it's going to come in once. You're not logged in, so it's redirecting, its going to go out, but then it's going to come in back again, and this time the user is redirected and so it's going to show you the page. So you end up going through this twice. Now, that's the bad way to do it or the wordy way to do it. It's only five lines of code, but I don't like five lines of code. So there's this thing called a mixin. A mixin is a class. The idea of a mixin is that we have an inherited class. We inherit things that are just a feature almost. So what we're doing is, we're going to take our protect view. It really extends a view, but it's going to also add the capabilities of login required mixin. So login required mixin basically says to Django, if this is here, "Hey, I want to do this. Don't let the user enter this particular view. You protect the view." So this is another protected view, but by simply including this little signal that says login required mixin, I've mixed this into my view, then it does all this work for us. So what'll happen is, it won't even come in if the user is not logged in, it will redirect and then come back, and then let this code in the get run only when the user's logged in. So this is by far the most common way to do it. It's just call LoginRequiredMixin, saving you from writing all these lines of code. So all these extra things, do I remember how to do this? What if I write that 5,000 times in the application? It's really silly when we've got LoginRequiredMixin that takes care of all this stuff. Just to review, this is what that view looks like. It just dumps all that stuff out. I use the same template for all of these views. So login, like many things in Django, is simple. It's easy. You add the things to install the apps and URL patterns, you make yourself a template. I didn't go in great detail. Django has great documentation if you want to get really sophisticated. What I tend to do is I get one or two templates working for login. I'm like, "I want to use this one today or that one." So this is where the sample code has two different logins that we're going to use. One is a simple local login and the other one actually is a login when we're going to use GitHub to do our logins. I get to use URLs for login with reverse, reverse_lazy, or the URL template tag. Then if we want to come back, we add a next parameter to those URLs. Then when we have a view and we say, "Look, this view is going to depend on request.user or the user template tag. Just add LoginRequiredMixin and then Django takes care of making sure that you can't get to the view unless you're logged in. If you try to get to the view, it tries to let you log in. If you're login successful, you come back to the view and it's all transparent to you. It's literally just one little common thing in the create. So it's pretty simple, it's pretty awesome. I just want you to understand what's going on because again, sometimes the fewer the lines of code to write, the harder it is to understand. Cheers.