Django Extending User model

Django only provides bare minimum fields in the User model to get you started, but it also gives you full power to extend the User model to suit your application needs.

Recall that by default User model contains the following fields:

  1. username
  2. first_name
  3. last_name
  4. email
  5. password
  6. last_login
  7. is_active
  8. is_staff
  9. is_superuser
  10. date_joined

The first step in extending a User model is to create a new model with all the additional fields you want to store. To associate our new model with the User model define a OneToOneField containing a reference to the User model in our new model.

Open blog’s models.py and modify Author model as follows:

TGDB/django_project/blog/models.py

Here we have defined two extra fields, namely activation_key and email_validated. Each of these fields does the following:

Field Description
activation_key It stores a random unique key sent during email verification. The user must click on the link containing activation_key to activate the account.
email_validated The email_validated field stores boolean data i.e 0 or 1. If an account is validated it contains 1. Otherwise, 0.

Before we run makemigration command comment out the AuthorAdmin class and also remove it from the admin.site.register() function. At this point, blog’s admin.py should look like this:

TGDB/django_project/blog/admin.py

In the terminal or command prompt, create new migration file by executing the following command:

When asked for Did you rename author.active to author.email_validated (a BooleanField)? [y/N], hit N or n.

Finally, commit the changes using python manage.py migrate command.

Let’s update our cadmin’s register() view to send email verification to the newly created accounts.

TGDB/django_project/cadmin/views.py

Here is rundown of the changes we have made in register() view:

1. In line 18, we are creating an activation_key based upon the username entered using generate_activation_key() helper function. The generate_activation_key() function is defined in helpers.py file as follows:

TGDB/django_project/django_project/helpers.py

2. In line 29, we are sending email verification using send_email() function. The syntax of send_mail() function is:

On success, it returns 1, otherwise 0.

If an error is encountered while sending email verification we set error to True.

3. If no error is encountered while sending an email then we proceed to create new User. Notice how we are saving the additional User data into the database.

In lines 37-42, we are using create_user() method to save built-in fields of User model. At this point, additional user data like activation_key and email_validated is not yet saved into the database. In lines 45 and 46, we are setting values to activation_key and user field. And in line 47, we are saving additional User data by calling save() method on the Author object.

Next, add another view called activate_account() in cadmin’s views.py file, whose job is to set is_active and email_validated field to True when the user clicks on the verification link in the email.

TGDB/django_project/cadmin/views.py

Create a new template activated.html for activate_account() view and add the following code to it:

TGDB/django_project/cadmin/templates/cadmin/activated.html

Finally, add a URL pattern named activate just above the register URL pattern in cadmin’s urls.py file as follows:

TGDB/django_project/cadmin/urls.py

Our user registration form is now ready. Visit http://127.0.0.1:8000/cadmin/register/ and create a new user.

If registration succeeds, you will be greeted with a success message and email containing a verification link will be sent to the email id provided at the time of registration.

To verify your account click on the verification link and you will be greeted with “Account successfully verified. Please login.” message.

Your account is now active and can be used to login. Visit http://127.0.0.1:8000/cadmin/login/ and login with your newly created account.

If user registration failed due to duplicate username/email or unmatching password the form will display validation errors like this:

In case, Django unable to send email verification then you will get an error like this:

Removing obsolete data

If you now visit post add or update page you will notice an error like this:

The problem is that in the process of committing changes to the Author model our last migration also has removed all the authors from the blog_authors table. Only the authors which we created via User Registration form after updating Author models are valid.

To fix the issue, designate all the posts to author(s) which is connected to the User model. In my case, I am designating all post to an author whose username is charmander. To do so, execute the following SQL.

The exact author_id may vary.

Finally, delete all the posts authors which are not connected to the User model.

While we are at it, let’s update author of category and tags too:

Visit post add or post update page and the error would have gone.

Note: To checkout this version of the repository type git checkout 33a.

Leave a Comment