NOTE: This article was initially posted on my Substack, at https://andresalvareziglesias.substack.com/
This is the last chapter of this Django AllAuth series of posts. In these five chapters we have discovered a little piece of wonder, a really helpful Django component to handle all our authentication needs. In this chapter we are going to learn how to extend the basic Django user model to add custom fields.
AllAuth uses the standard Django user model, plus some extra tables to handle social login and login tokens. In Django 5, the user model is located in the django.contrib.auth package, and has a bunch of predefined fields, as you can read in the official doc:
Sometimes, this is not enough for our project. Django allows you to create custom User tables and User managers, to handle the needs of every project.
We are going to create a custom User table and a custom UserManager to handle our login and register processes.
Open models.py in our sample project an write a code like this:
class MyCustomUser(AbstractBaseUser): email = models.EmailField(unique=True) first_name = models.CharField(max_length=30, blank=True) last_name = models.CharField(max_length=30, blank=True) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) timezone = models.CharField(max_length=30, default='UTC') is_custom = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) objects = MyCustomUserManager() USERNAME_FIELD = 'email' EMAIL_FIELD = 'email' def __str__(self): return self.email def has_perm(self, perm, obj=None): return True def has_module_perms(self, app_label): return True @property def is_utc(self): return self.timezone == 'UTC'
We can define a new User model extending from Django's AbstractBaseUser model. In this new model we can add all fields or custom properties that we need.
These lines are important:
objects = MyCustomUserManager() USERNAME_FIELD = 'email' EMAIL_FIELD = 'email'
With these lines we are linking the user model with our custom UserManager, and we are also defining the field acting as a unique "username".
Remember to register the new model in admin.py to manage it from the Django admin tool.
from django.contrib import admin from .models import MyCustomUser admin.site.register(MyCustomUser)
Open again models.py in our sample project (or generate another file for the custom UserManager if you want) an write a code like this:
class MyCustomUserManager(BaseUserManager): def create_user(self, email, password=None): if not email: raise ValueError('Users must have an email address') user = self.model( email=self.normalize_email(email), ) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password): user = self.create_user( email=email, password=password, ) user.is_admin = True user.is_staff = True user.save(using=self._db) return user
In this example we are extending BaseUserManager to create our custom UserManager. It creates our new users, and fills the custom fields as we expect.
We defined before the UserManager for our custom User model, so Django knows what class to use during new user creation.
In the settings file of our project we can set the current user model for our project with:
# Set custom user model as the active one AUTH_USER_MODEL = 'demo.MyCustomUser' # Configure AllAuth username related management, because we are # using the e-mail as username. See: # https://docs.allauth.org/en/latest/account/advanced.html ACCOUNT_AUTHENTICATION_METHOD = 'email' ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_USERNAME_REQUIRED = False ACCOUNT_USER_MODEL_USERNAME_FIELD = None
With just this small change (and the required DB migration, as usual), we can start to create users with AllAuth signup views to see our shiny custom UserManager and its model in action. Quick and easy.
We are also disabling the AllAuth username related management, because we are using the e-mail as username in this example.
We have reached the last chapter on this AllAuth series. AllAuth is a wonderful library to handle the authentication in our apps, and makes it especially easy to work with social logins, thanks to its large list of predefined integrations.
This is the last chapter of the series, but I will revisit AllAuth in future posts. Thanks for reading and happy coding!
Among the Python and Docker posts, I will also write about other related topics (always tech and programming topics, I promise... with the fingers crossed), like:
If you found some interesting technology, programming language or whatever, please, let me know! I'm always open to learning something new!
I'm Andrés, a full-stack software developer based in Palma, on a personal journey to improve my coding skills. I'm also a self-published fantasy writer with four published novels to my name. Feel free to ask me anything!
The above is the detailed content of Django AllAuth Chapter Extending Django AllAuth user model with custom fields. For more information, please follow other related articles on the PHP Chinese website!