How To Sign Up And Log In Users With Django

How To Sign Up And Log In Users With Django

Django has some tools built in that you can use to set up the ability for users to log in and log out of a web application. In this tutorial, we’ll see how to set that functionality up. First, we’ll set up the url patterns and routes that we need, then we’ll configure the needed view functions. In the view functions, we’ll make use of two really cool classes the Django offers. Those are the UserCreationForm and the AuthenticationForm classes. These two classes provide a way to scaffold out the entire sign up and login configuration of the forms to handle these tasks, with validation built right in. Let’s get started.

Accounts App

We’ll begin by creating a new app in our Django project named accounts to hold the files we’ll need for login and log out functions.

djangoblog $python manage.py startapp accounts

django accounts app

Register App With Django

Anytime you want to use a new app inside of a Django project, you need to register it in the settings.py file. Below we see two custom apps in our Django project, one for posts, and one for accounts.

djangoblog/settings.py

Adding urls.py

The startapp does not automatically generate a urls.py file in the new app that it creates. We’ll need one for this app, so in Pycharm, we can add that file now.

add urlspy to app

Namespace and URL Patterns

To begin, we need a way to display a form to a user of the application to offer a chance to sign up. Also, note that we are giving this app a namespace of accounts. That way when using named routes, Django will not be confused if there are routes with the same name in different apps. It can use the namespace to determine which is which.

accounts/urls.py

The above code simply defines a pattern such that if a user visits /signup within the /accounts namespace, a signup_view() function will be triggered. We’ll see what that function does in a little bit.

Including URLS

We’ve seen this pattern a few times now in the course of our Django tutorials, and that is including the url patterns from an app, in the base urls.py file of the Django project. The highlighted code below ensures that anytime a user visits http://example.com/accounts, they will then be making use of the url patterns defined in accounts/urls.py (shown just above).

djangoblog/urls.py

Defining View Functions

Now we can define some view functions to handle the Http requests. First, we define a signup_view() which accepts the Http request, then returns a render of the signup.html template which we will create in a moment.

accounts/views.py

In Pycharm we can choose to add a new directory and provide the path of templates/accounts which gives us a nice namespace for our templates in accounts/templates/accounts.

django namespaced templates

Then in our new directory, we add the signup.html template.

pycharm new html file

We’ll also define a layout folder to hold a base.html template we can extend from.

base template django

In the layout directory, we create that base.html file like so.

extend base html django

The contents of the base.html template are shown here. This is the same setup that we learned about in the static files and images tutorial for Django.

accounts/templates/accounts/layout/base.html

The signup.html template then extends from that base layout, and for now we just add a simple h1 tag to let us know that this is the signup page.

accounts/templates/accounts/signup.html

Well, that was a few steps to take, but now we should have a working scenario when visiting http://localhost:8000/accounts/signup/. First make sure the Django server is running by typing python manage.py runserver at the terminal, then visit the url. Looking good!

django user sign up page


Django UserCreationForm

Now we get to some really cool magic with Django. The UserCreationForm() is one such piece of magic. This class is what is known as a Model Form. What makes it so cool is that it does a slew of steps for you in one go, including generating the Html markup for the form to display in the template.

A ModelForm for creating a new user.

It has three fields: username (from the user model), password1, and password2. It verifies that password1 and password2 match, validates the password using validate_password(), and sets the user’s password using set_password().

To use this model form, we first import it at the top of the file. On line 7 a new instance of this model form is created using form = UserCreationForm(). On line 8 in the render() function, we can pass that form over to the template using the dictionary as the third parameter.

accounts/views.py

Now in the signup.html template, we only manually add the opening and closing <form> tags. In between the opening and closing <form> tags, all you have to do is use {{ form }} to output a very nice looking user signup form.

accounts/templates/accounts/signup.html

If we visit http://localhost:8000/accounts/signup/ we are now seeing that nice user signup form, and it really was a minimal effort.

django usercreationform output

Here is the Html that the default instance of UserCreationForm outputs. No need for you to write all of that Html markup from scratch.

Adding A Submit Button

One thing that was not included in the form generation is a submit button. We can add one manually as we see in the highlighted code below.

Now we have the entire form, with submit button ready to go!

django usercreationform submit button


Saving Users

Now we want to wire up the signup_view() function so that it detects the form submit verb in use, and takes appropriate action based on whether it is a POST request or a GET request. In the code below, if there is a POST request detected, then we take the contents of the form and store it into that form variable using form = UserCreationForm(request.POST). To validate the form, all you have to do is use form.is_valid(). Finally, if that checks out you can save the user with form.save(), then redirect to the list of posts using return redirect(‘posts:list’). The else condition handles the GET request, and simply creates a blank form and sends it to the signup template.

accounts/views.py

CSRF Token

Before we go trying to submit this form, we need to make sure we include a csrf token for validation. A csrf token ensures that the request being sent to the Django application is valid and secure. To add a csrf token to a Django form, use the template tags like so {% csrf_token %}.

First off, we are going to try signing up a new user, but we can use a bad password.

enter info usercreationform django

Djangos UserCreationForm is working perfectly. It handles the validation automatically and provides tips on how to fix the problem. Very nice!

django form automatic validation

This time around, when we provide input that meets all of the requirements, the form submits successfully and we are redirected just like the code in our view function is set up to do.

redirect after django form submit

In fact, this has now saved our new user to the database. We can check in the admin area, and look at that, our new user!

new user is saved to the database

Note that when a new user is created via the front end, it is a normal user with limited rights – which makes perfect sense.

no admin rights for new users


Display an AuthenticationForm

At this point, the form is creating a new user in the application. We are not yet logging them in, however. Additionally, there is no way for the user to even try to log in. This is where we get to play with another piece of magic in Django, and that is the AuthenticationForm() class. First off, we need a new route, view function, and template to display the login form.

The code here sets up a login/ route, points to the login_view() function, and is named login.
accounts/urls.py

The highlighted code below shows how we can use the AuthenticationForm in the login_view() function of views.py
accounts/views.py

Finally, we need a login.html template to display a login form to the user. The form is output in the template in a similar way as when we were using the UserCreationForm. The action of the form is set using template tags and the url function to a named route. We also include a csrf token just like before.

accounts/templates/accounts/login.html

Now we can test it out. If we don’t use the right credentials, the form works perfectly and lets us know.

log in with bad creds example

However, once we provide the right credentials, the form submits and redirects us as we want.

good login then redirect


Log User Into Application

In this step, we are going to add the code to log in a user. In the step above, the form submitted and redirected us, but the code to actually establish a session with the application was not in place. The highlighted code below completes the login process for us.

accounts/views.py

Once we fill out the login form and log in, we can check our logged-in status by visiting the admin area. It says we are in fact authenticated, but that we don’t have permission to be in the admin area as Sonic. This proves that our session with the application is in fact now established.

Django user account login


How To Log Out A User

We also need the ability to log out of the application. Here is how we can set that up. First off, we add the route needed in the urls.py file. The highlighted line defines a /logout route, points to a logout_view() function, and is named logout.

accounts/urls.py

To log a user out, the highlighted code below is used. It does not need an actual template. All it does is to check if the user has sent a POST request to this route, and if so, call the logout() function while passing in the request. Once complete, just redirect back to the list of posts. Django is smart enough to know which user this is and log them out. All of that information is carried in the request object.

accounts/views.py

Show Log Out Button

We should display a log out button to the user, but only if the user is currently logged in. Django gives us a neat way to check for this using the is_authenticated property on the user object. You can reference it in your Django templates using {% if user.is_authenticated %}. So in the code below, the log out button is used in a form tag. This way we can set up the button to easily send a POST request for the log out which is a best practice. Also, note that this form/button only displays if the user is actually authenticated.

posts/templates/posts/layout/base.html

Now, when we are logged in, we do see the option to logout.

django useris_authenticated example

Clicking that button logs the user out, and redirects back to the post list. Excellent!

log out and redirect django

Learn More

How To Sign Up And Log In Users With Django Summary

Django provides a robust authentication system for your web applications. It covers all of the most common use cases of an authentication system and makes use of some really cool classes like UserCreationForm and AuthenticationForm. This tutorial and the associated resources should have you up and running the Django Authentication in no time!