Django Login/Logout System Part-I
Hana Belay
Posted on August 27, 2021
Hey guys, how have you been? In today's part we are going to create the login system with a remember me cookie option
Here again, we don't have to reinvent the wheel thanks for the built in django's authentication system. We can build our authentication system by extending from that and customize it to meet our needs.
Django gives this authentication support in its module django.contrib.auth
whose configuration is already included in settings.py when we created our project in the very beginning. This built in auth app gives us login, and logout views together with other password management views that we will go over in later parts of the series.
- Great. Now let's see how we can put all this together.
Let's start from the login form. Django has a built in AuthenticationForm
which is a base class for authenticating users based on username and password.
We will create our login from by extending from it to add a remember me checkbox, and also bootstrapify the username and password fields using widgets as we saw in the previous posts.
A remember me option is a nice to have feature since users don't want to fill in credentials every time they visit a site.
forms.py
# Add this to previous list of imports
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
class LoginForm(AuthenticationForm):
username = forms.CharField(max_length=100,
required=True,
widget=forms.TextInput(attrs={'placeholder': 'Username',
'class': 'form-control',
}))
password = forms.CharField(max_length=50,
required=True,
widget=forms.PasswordInput(attrs={'placeholder': 'Password',
'class': 'form-control',
'data-toggle': 'password',
'id': 'password',
'name': 'password',
}))
remember_me = forms.BooleanField(required=False)
class Meta:
model = User
fields = ['username', 'password', 'remember_me']
- We have seen how forms are created in the last part when we created the sign up form so we won't go much into detail here.
Next, let's set up the view to use the login form we created. Django also has a built in LoginView. We can override some of the class's attributes and methods to meet our needs.
views.py
from django.contrib.auth.views import LoginView
from .forms import RegisterForm, LoginForm
# Class based view that extends from the built in login view to add a remember me functionality
class CustomLoginView(LoginView):
form_class = LoginForm
def form_valid(self, form):
remember_me = form.cleaned_data.get('remember_me')
if not remember_me:
# set session expiry to 0 seconds. So it will automatically close the session after the browser is closed.
self.request.session.set_expiry(0)
# Set session as modified to force data updates/cookie to be saved.
self.request.session.modified = True
# else browser session will be as long as the session cookie time "SESSION_COOKIE_AGE" defined in settings.py
return super(CustomLoginView, self).form_valid(form)
The first thing we did is set the
form_class
attribute to our customLoginForm
since we are no longer using the defaultAuthenticationForm
.Next we overrode the
form_valid
method which is called when valid form data has been posted. Inside this method we checked to see whether or not the remember_me check box is checked (a lot of "checks" there, am having a tongue twister:) ).If it's not checked, session will expire automatically when the browser is closed. But for the users who check on the remember_me box, the session will last as long as we define it in settings.py.
So let's go ahead and set the
SESSION_COOKIE_AGE
to 30 days (or as long as you want it to last) in the settings.
settings.py
SESSION_COOKIE_AGE = 60 * 60 * 24 * 30
- Great. Now inside our main project's urls.py let's map the desired login route to the corresponding CustomLoginView.
- While we are at it, let's also create the logout route which will be handled by the built in
LogoutView
.
user_management/urls.py
# Add the following to the list of previous imports
from django.contrib.auth import views as auth_views
from users.views import CustomLoginView
from users.forms import LoginForm
urlpatterns = [
# Add this path
path('login/', CustomLoginView.as_view(redirect_authenticated_user=True, template_name='users/login.html',
authentication_form=LoginForm), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
]
redirect_authenticated_user=True
means that users who try to access the login page after they are authenticated will be redirected back.Templates aren't part of the resources the auth app gives us, so we need to provide a template both for the login and logout views. By default django looks for these template in registration directory. But we can override this default behavior and tell django to look for login and logout templates inside users/templates/users/ directory. We can do this by passing in the
template_name
as an argument toas_view
function.authentication_form=LoginForm
- since we are using our extended login form.
After successful login, by default django redirects the user to a profile page. We can also modify this in our settings.py file, so let's open that up.
settings.py
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = 'login'
-
LOGIN_REDIRECT_URL
tells django to redirect the user to the home page after a successful login. - The
LOGIN_URL
is the URL or named URL pattern where requests are redirected for login when we are trying to limit access to certain pages. It defaults to '/accounts/login/'. But since we put our login route at/login
,LOGIN_URL
tells django where it can find this route.
That's it for part-I of login/logout system. In the next part we will create the templates and modify some stuffs. Stay tuned!
Thanks for your time, you can find the finished app in github.
Feel free to ask, and any suggestions are welcome. See ya!
Posted on August 27, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.