Django's built-in User
model is not always appropiate for some kinds of projects. On some sites it might make more sense to use an email address instead of a username for instance.
You can override the default User
model adding your customized User
model to the AUTH_USER_MODEL
setting, in your projects settings file:
AUTH_USER_MODEL = 'myapp.MyUser'
Note that it's highly adviced to create the AUTH_USER_MODEL
before creating any migrations or running manage.py migrate
for the first time. Due to limitations of Django's synamic dependecy feature.
For example on your blog you might want other authors to be able to sign-in with an email address instead of the regular username, so we create a custom User
model with an email address as USERNAME_FIELD
:
from django.contrib.auth.models import AbstractBaseUser
class CustomUser(AbstractBaseUser):
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
By inherinting the AbstractBaseUser
we can construct a compliant User
model. AbstractBaseUser
provides the core implementation of a User
model.
In order to let the Django manage.py createsuperuser
command know which other fields al required we can specify a REQUIRED_FIELDS
. This value has no effect in other parts of Django!
class CustomUser(AbstractBaseUser):
...
first_name = models.CharField(max_length=254)
last_name = models.CharField(max_length=254)
...
REQUIRED_FIELDS = ['first_name', 'last_name']
To be compliant with other part of Django we still have to specify the value is_active
, the functions get_full_name()
and get_short_name()
:
class CustomUser(AbstractBaseUser):
...
is_active = models.BooleanField(default=False)
...
def get_full_name(self):
full_name = "{0} {1}".format(self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
return self.first_name
You should also create a custom UserManager
for your User
model, which allows Django to use the create_user()
and create_superuser()
functions:
from django.contrib.auth.models import BaseUserManager
class CustomUserManager(BaseUserManager):
def create_user(self, email, first_name, last_name, 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.first_name = first_name
user.last_name = last_name
user.save(using=self._db)
return user
def create_superuser(self, email, first_name, last_name, password):
user = self.create_user(
email=email,
first_name=first_name,
last_name=last_name,
password=password,
)
user.is_admin = True
user.is_active = True
user.save(using=self.db)
return user