This tutorial is a series of tutorials, with a directory index at the beginning of each tutorial for ease of reading:

  • Basic setup
  • Extending the User model
  • registered
  • The login
  • Logout and page hopping
  • Change the password
  • Customize the authentication background

Djangos User authentication system provides a built-in User object that records a User’s username, password, and other personal information. Djangos built-in User model contains only the following key attributes:

  • Username is the username
  • The password, the password
  • Email, mail
  • The first_name,
  • Last_name, surname

For some sites, users may also have nicknames, avatars, signatures, and other attributes, so simply using Djangos built-in User model isn’t enough. Fortunately, the Django User system follows extensible design principles that make it easy to extend the User model.

Extend the user model with AbstractUser

This is the recommended practice. In fact, if you look at the source code of User model, you know that User also inherits AbstractUser abstract base class, and only inherits AbstractUser, without making any extension to AbstractUser. Here is the User source code:

class User(AbstractUser):
    """ Users within the Django authentication system are represented by this model. Username, password and email are required. Other fields are optional. """
    class Meta(AbstractUser.Meta):
        swappable = 'AUTH_USER_MODEL'Copy the code

So, if we inherit AbstractUser, we’ll have all the features of User, and we’ll be able to extend it to suit our own needs.

We created a New Users application, and we usually put the code related to the database model in the models.py file. Open the users/models.py file and write our custom user model code:

users/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    nickname = models.CharField(max_length=50, blank=True)

    class Meta(AbstractUser.Meta):
        passCopy the code

We added a nickname property to the custom user model to record the nickname information of the user. The blank=True property was set so that the user did not need to fill in the nickname during registration. You can expand it to suit your needs, adding avatars, personality signatures, etc. There is no limit to how many property fields you can add.

Also, we inherit AbstractUser’s inner class property Meta, but so far we’re doing nothing. The reason to inherit Meta here is because you may need to set some Meta class attribute values in your project, and don’t forget to inherit the existing attributes in AbstractUser.meta.

Note: AbstractUser must be inherited, not auth.user. AbstractUser is an abstract class and auth.User is not, although auth.User inherits AbstractUser without any additional extension. If you inherit from auth.User, this becomes multi-table inheritance, which is not recommended at this point. For information about Django’s abstract model classes and multi-table inheritance, check out Django’s official document Model Inheritance.

In addition, AbstractUser class also inherits AbstractBaseUser, and the former extends a set of user Permission system based on the latter. So try not to extend from AbstractBaseUser unless you have a special need, or you’ll need to do extra work.

In order for Django user authentication to use our custom user model, we must specify the location of the custom user model with AUTH_USER_MODEL in settings.py.

django_auth_example/settings.py

# Other Settings...
AUTH_USER_MODEL = 'users.User'Copy the code

That is, tell Django to use the User User model in the Users application.

Also modify the language Settings and time zone Settings:

django_auth_example/settings.py

# Other Settings...

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'Copy the code

After the custom user model is set up, the database migration file is generated and the database is migrated to generate the necessary database tables for each application. Run the following two commands:

$ python manage.py makemigrations
$ python manage.py migrateCopy the code

OK, now the User model used by the Django User system is the custom User model.

Note: Be sure to set AUTH_USER_MODEL = ‘users.user’ before executing the database migration command the first time, i.e. after specifying the custom User model.

Extend the user model with the Profile pattern

If you want to extend the User model for a project that already uses Djangos built-in User model, this kind of extension can get a little cumbersome. Django doesn’t provide an automated way to migrate built-in users to a custom User model, because Django already generates database migration files and database tables for the built-in User model. To do so, manually modify the migration files and database tables and move the relevant user data in the database.

So we extend the User model in a way that doesn’t change the database tables. Specifically, we create a model (usually called a Profile) to record user-related data, and then associate that Profile with users in a one-to-one fashion. It is as if each user is associated with a table of personal information. The code is as follows:

models.py

from django.contrib.auth.models import User

class Profile(models.Model):
    nickname = models.CharField(max_length=50, blank=True)
    user = models.OneToOneField(User)Copy the code

The difference between this approach and AbstractUser is that the user model that inherits AbstractUser has only one database table. The Profile pattern has two tables, one corresponding to the User model and one corresponding to the Profile model, and the two tables are related by one-to-one relationship. As you can see, when querying a user’s Profile, you need to perform additional cross-table queries, so this approach is a little less efficient than directly inheriting AbstractUser. Therefore, for new projects, it is recommended to extend the user model in a way that inherits AbstractUser.

PS: If you use the Profile pattern, you may want to create a Profile object associated with the User object as well. You can do this using Djangos Signal. Since the Profile pattern is not the focus of our discussion, please refer to the relevant documentation for implementation details.

OK, now that the custom User model is established, it’s time to create the User, the User registration process.

conclusion

The sample project code for this tutorial is located at GitHub: Django Auth Example.

If you have problems, please ask for help in the following ways.

  • Leave a comment in the comments section of Djangos User Authentication System: Extending the User Model.
  • Post a detailed description of the problem in the Django section of Pythonzhcn.

For more Django tutorials, visit my personal blog, Dreamers Blog.