Now that we have our custom user model we can go ahead and create a manager so
Django knows how to work with this custom user model in the Django
command-line tools one of the commands that we're going to be using in a future
video is the create super user command this is a command that's provided with
the Django CLI that makes it really easy to add super users to the system so a
super user is an administrator user that will have full control and be able to
access the Django admin and see all the models in the database now because we've
customized our user model we need to tell Django how to interact with this
user model in order to create users because by default when it creates a
user it expects a username field and a password field but we've replaced the
username field with an email field so we just need to create a custom manager
that can handle creating users with an email field instead of a username field
so let's go ahead and create our custom user manager in our models dot py file
I like to create the manager file just above the model that it is going to be
used for so above the class user model or user profile' create another couple
of lines and then create a new class called user profile manager and we're
going to inherit from the base user manager which is the default manager model that
comes with Django so we have to import that here below our Django dot contrib dot auth dot models imports
let's create a new line from Django dot contrib dot auth dot models
import base user manager
PEP-8 guidelines say that the classes in a Python module
should be two spaces between them so make sure there's two spaces below the
new class that we create and the original class and I also like to use
leave two spaces between the imports and the class as well I'll link to the PEP-8
guidelines in the resources of this video if you
want to learn more about that
Okay so in our user profile manager class let's add
base user manager as a parent class and then do : and then let's specify a
docstring here manager for user profiles
The way managers work is you specify
some functions within the manager that can be used to manipulate objects within
the model that the manager is for so the first function that we need to create is
the create underscore user function this is what the Django CLI will use when
creating users with the command line tool
So type def to define a function
create underscore user and then open brackets and because it's a class
function we need to specify self as the first argument and then the second
argument will be email the third argument will be name and the fourth
argument will be password equals none so this means that if you don't specify a
password then it will default to none and because of the way the Django
password checking system works a non password won't work because it needs to
be a hash so basically until you set a password you won't be able to
authenticate with the user
Ok below this functions create a doc string create a
new user profile so that's what this function does and then we'll do a check
to see if an email address has been provided so we'll do if not email so if
the email has been passed in as either an empty string or a null value then we
will raise a value error exception so this is the standard behavior that
Python expects and what it can do is it can catch our value error
exception and display the message on the screen so if you were to not provide an
email address then you define the message that you show to
users if they try and create a new user profile without an email
so let's type raise value error
users must have an email address
Okay so this
is just to make sure that the user...well when we call this function that a
an email address value has been passed in
Next we're going to do something
called normalize the email address now what normalizing an email address
does is it makes the second half of the email address all lowercase
so technically with an email address the first half of the email is
case-sensitive that means you could have two separate email addresses with the
capital letters or with lower case letters and then the second half is
always case insensitive so it's best practice to standardize that by making
it lowercase now a lot of email providers such
as Gmail and Hotmail and things like that will make the first half case
insensitive as well just for convenience but technically it could be case
sensitive depending on the email provider so that's why normalized email
only takes care of the second half
Okay so let's set email equals self dot
normalize underscore email email
so we have our normalized email
address next we will create our user model by typing user equals self dot model
email equals email and name equals name
now what this does is it creates a new
model that the user manager is representing so by default self dot model is
set to the model that the manager is for and then it will create a
new model object and set the email and the name
Next we're going to set the
password and we can't just pass the password in here as a clear text value
we need to use the set password function that comes with our user model so it's
part of the abstract base user and we set this by doing user dot set
password password and pass it in like that the reason we do that is so the
password is encrypted we want to make sure the password is converted to a hash
and never stored as plain text in the database because this way if somebody
should manage to hack the database and retrieve all the users they would only
be able to see the hashed passwords which means they wouldn't be able to
convert that password to a clear text password and then potentially use that
to log into the users other services if they used the same password for Facebook
or another website for example
They could technically reverse-engineer it
eventually if they'd given it enough time so it doesn't mean you don't have
to protect your database but it's the best practice for storing any sensitive
data in the database is to encrypt it and by default Django does this with the
set password function
Okay now we can save the user model so type user dot
Save and then the standard is to specify the database that you want to use so
Django can support multiple databases and we're only going to be using one database
but it's best practice to add this line anyway just to make sure that you
support multiple databases in the future if you should at it so type using equals
self dot underscore DB
Again this is the standard Django basically the standard
procedure for saving objects in Django and this is described in the Django
documentation which I'll link in the resources of the video
Alright now we
can return the user so after we create the user we're going to return the newly
created user object so type return user
and that is our create user
function
ok the next function we need to create is the create super user function
and this will use our create user function to create a new user but also
assign a super user status so it's an admin user in the system
So create a new function def create super user and we're going to pass in the
argument self email name and password we're not going to allow the password to
be non in this one because we want all super users to have a password and then
we will add a docstring create and save a new super user with given details
Ok now we will use the create user function to create a user so we'll just do user
equals self dot create underscore user actually it is not an underscore there so
self dot create user and open brackets
we will pass in email address name and
password
So it might seem a bit confusing here because we have self here
we didn't pass self in self is automatically passed in for any class
functions so when you call it from a different function or a different part
of the code you don't need to specify self because it gets automatically
passed in when you call the function this is part of Python
Okay now that we
have the user in our super user function we're going to assign is super user to
equals true so user dot is super user equals true and then we'll set
staff equals true so user dot is staff equals true and then we will save our
user model user dot save and again we'll pass in using equals self DB and return
user
Okay if you're a bit confused as to where these is super user and is staff
items came from then that's because we didn't actually specify...well
we did specify is staff but we didn't specify is super user in our user model because
it automatically is created by the permissions mixin
Okay now we can save
the models dot py and that's all we need to do to create our
user model manager