How To: Create a Custom User using Mixins
Warning
This configuration method is but one of three, and may not make the most sense for your project. Please read Select a Configuration Method for Improved User before continuing, or else follow the instructions in Quickstart: Using Improved User.
The User
and
AbstractUser
classes supplied by
the package are not always what you want. In some cases, they may supply
fields you do not need or wish for. This tutorial demonstrates how to
create User
models using the provided mix-in classes,
effectively building the model from scratch.
In this tutorial, we will create a new custom User that has an email
field and password, but which does not feature either the short_name
or full_name
fields.
Warning
Not supplying methods for names on the User model will cause problems with Django’s Admin.
Tip
If you’re looking to extend the
User
model, rather than replace
it as shown in this tutorial, use the following steps:
inherit
AbstractUser
(follow the instructions in Quickstart: Using Improved User to see how)add new fields as desired
override
REQUIRED_FIELDS
if necessary (remembering to put'short_name', 'full_name'
in the list)
In an existing app, in the models.py
file, we start by importing the
tools we need to build the model. We first import classes from Django.
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import gettext_lazy as _
AbstractBaseUser
and
PermissionsMixin
will serve as a
base for the User (click the classes in this sentence to see Django’s
official documentation on the subject). We also import
gettext_lazy()
to enable translation
of our strings.
We then import mix-in classes from Improved User.
from improved_user.managers import UserManager
from improved_user.model_mixins import DjangoIntegrationMixin, EmailAuthMixin
The DjangoIntegrationMixin
class
provides fields that allow the model to integrate with Django’s default
Authentication Backend as well as a field to allow for integration with
Django’s Admin.
The EmailAuthMixin
creates an
EmailField
and sets the field to be used
as the username during the authentication process.
The UserManager
is a custom model
manager that provides the
create_user()
and
create_superuser()
methods
used in Django.
Danger
Improved Users’ custom
UserManager
is intended to work
with subclasses of EmailAuthMixin
,
and will likely not work with your User subclass if you are using a
different field for your username. You will, in that case, need to
create your own UserManager
. The source code for Improved Users’
UserManager
as well as Django’s
BaseUserManager
and
UserManager
would likely prove
helpful.
Note
If you wanted to create a User model with a field other than email
for username, you would set the
USERNAME_FIELD
on
your User model to the name of the field that should serve as the
username. Please take a look at the source of
EmailAuthMixin
for an example of
this.
With all our tools in place, we can now create a User model. We start by
creating a class that inherits all of the classes we have imported, and
then we tie the UserManager
to the
new model.
class User(
DjangoIntegrationMixin, EmailAuthMixin, PermissionsMixin, AbstractBaseUser
):
"""A user created using mix-ins from Django and improved-user
Note that the lack of name methods will cause errors in the Admin
"""
For good measure, we can specify the name and verbose name of the model,
making sure to internationalize the strings. Our full and final
models.py
file is shown below.
"""A User model created by django-improved-user mixins"""
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import gettext_lazy as _
from improved_user.managers import UserManager
from improved_user.model_mixins import DjangoIntegrationMixin, EmailAuthMixin
class User(
DjangoIntegrationMixin, EmailAuthMixin, PermissionsMixin, AbstractBaseUser
):
"""A user created using mix-ins from Django and improved-user
Note that the lack of name methods will cause errors in the Admin
"""
objects = UserManager()
class Meta:
verbose_name = _("user")
verbose_name_plural = _("users")
Tip
Setting abstract = True
in the Meta
class would allow the
class above to be an AbstractUser model similar to
AbstractUser
For all of the classes you may use to create your own User
model, please see model_mixins
.