WEBVTT
Kind: captions
Language: en

00:00:00.030 --> 00:00:05.220
Now that we have our custom user model
we can go ahead and create a manager so

00:00:05.220 --> 00:00:08.940
Django knows how to work with this
custom user model in the Django

00:00:08.940 --> 00:00:13.950
command-line tools one of the commands
that we're going to be using in a future

00:00:13.950 --> 00:00:19.020
video is the create super user command
this is a command that's provided with

00:00:19.020 --> 00:00:23.519
the Django CLI that makes it really easy
to add super users to the system so a

00:00:23.519 --> 00:00:27.570
super user is an administrator user that
will have full control and be able to

00:00:27.570 --> 00:00:32.309
access the Django admin and see all the
models in the database now because we've

00:00:32.309 --> 00:00:37.980
customized our user model we need to
tell Django how to interact with this

00:00:37.980 --> 00:00:43.170
user model in order to create users
because by default when it creates a

00:00:43.170 --> 00:00:48.149
user it expects a username field and a
password field but we've replaced the

00:00:48.149 --> 00:00:53.129
username field with an email field so we
just need to create a custom manager

00:00:53.129 --> 00:00:58.460
that can handle creating users with an
email field instead of a username field

00:00:59.040 --> 00:01:04.840
so let's go ahead and create our custom
user manager in our models dot py file

00:01:04.850 --> 00:01:10.380
I like to create the manager file just
above the model that it is going to be

00:01:10.380 --> 00:01:16.619
used for so above the class user model
or user profile' create another couple

00:01:16.619 --> 00:01:25.049
of lines and then create a new class
called user profile manager and we're

00:01:25.049 --> 00:01:30.329
going to inherit from the base user manager
which is the default manager model that

00:01:30.329 --> 00:01:36.680
comes with Django so we have to import that here below our Django dot contrib dot auth dot models imports

00:01:36.680 --> 00:01:43.310
let's create a new line from Django dot contrib dot auth dot models

00:01:43.310 --> 00:01:49.520
import base user manager

00:01:49.520 --> 00:01:54.000
PEP-8 guidelines
say that the classes in a Python module

00:01:54.000 --> 00:01:58.799
should be two spaces between them so
make sure there's two spaces below the

00:01:58.799 --> 00:02:02.310
new class that we create and the
original class and I also like to use

00:02:02.310 --> 00:02:08.009
leave two spaces between the imports and
the class as well I'll link to the PEP-8

00:02:08.009 --> 00:02:11.290
guidelines in the resources of this
video if you

00:02:11.290 --> 00:02:13.800
want to learn more about that

00:02:13.800 --> 00:02:17.859
Okay so in our user profile manager class let's add

00:02:17.859 --> 00:02:25.689
base user manager as a parent class and
then do : and then let's specify a

00:02:25.689 --> 00:02:31.980
docstring here manager for user profiles

00:02:31.980 --> 00:02:34.220
The way managers work is you specify

00:02:34.220 --> 00:02:39.370
some functions within the manager that
can be used to manipulate objects within

00:02:39.370 --> 00:02:45.069
the model that the manager is for so the
first function that we need to create is

00:02:45.069 --> 00:02:50.829
the create underscore user function this
is what the Django CLI will use when

00:02:50.829 --> 00:02:53.940
creating users with the command line
tool

00:02:53.940 --> 00:02:56.370
So type def to define a function

00:02:56.370 --> 00:03:03.099
create underscore user and then open
brackets and because it's a class

00:03:03.099 --> 00:03:08.079
function we need to specify self as the
first argument and then the second

00:03:08.079 --> 00:03:13.659
argument will be email the third
argument will be name and the fourth

00:03:13.659 --> 00:03:19.540
argument will be password equals none so
this means that if you don't specify a

00:03:19.540 --> 00:03:24.760
password then it will default to none
and because of the way the Django

00:03:24.760 --> 00:03:29.560
password checking system works a non
password won't work because it needs to

00:03:29.560 --> 00:03:33.129
be a hash so basically until you set a
password you won't be able to

00:03:33.129 --> 00:03:35.980
authenticate with the user

00:03:35.980 --> 00:03:40.989
Ok below this
functions create a doc string create a

00:03:40.989 --> 00:03:47.470
new user profile so that's what this
function does and then we'll do a check

00:03:47.470 --> 00:03:55.389
to see if an email address has been
provided so we'll do if not email so if

00:03:55.389 --> 00:04:02.260
the email has been passed in as either
an empty string or a null value then we

00:04:02.260 --> 00:04:06.849
will raise a value error exception so
this is the standard behavior that

00:04:06.849 --> 00:04:12.069
Python expects and what it can do is it
can catch our value error

00:04:12.069 --> 00:04:16.659
exception and display the message on the
screen so if you were to not provide an

00:04:16.659 --> 00:04:19.900
email address then you define the message that you show to

00:04:19.900 --> 00:04:24.139
users if they try and create a new user
profile without an email

00:04:24.139 --> 00:04:30.580
so let's type raise value error

00:04:30.580 --> 00:04:36.700
users
must have an email address

00:04:36.700 --> 00:04:37.580
Okay so this

00:04:37.580 --> 00:04:41.960
is just to make sure that the user...well
when we call this function that a

00:04:41.960 --> 00:04:44.940
an email address value has been passed
in

00:04:44.940 --> 00:04:46.550
Next we're going to do something

00:04:46.550 --> 00:04:50.719
called normalize the email address
now what normalizing an email address

00:04:50.719 --> 00:04:54.770
does is it makes the second half of the
email address all lowercase

00:04:54.770 --> 00:05:01.370
so technically with an email
address the first half of the email is

00:05:01.370 --> 00:05:06.139
case-sensitive that means you could have
two separate email addresses with the

00:05:06.139 --> 00:05:10.580
capital letters or with lower case
letters and then the second half is

00:05:10.580 --> 00:05:15.830
always case insensitive so it's best
practice to standardize that by making

00:05:15.830 --> 00:05:20.719
it lowercase now a lot of email providers such

00:05:20.719 --> 00:05:26.150
as Gmail and Hotmail and things like
that will make the first half case

00:05:26.150 --> 00:05:30.409
insensitive as well just for convenience
but technically it could be case

00:05:30.409 --> 00:05:33.830
sensitive depending on the email
provider so that's why normalized email

00:05:33.830 --> 00:05:37.180
only takes care of the second half

00:05:37.180 --> 00:05:41.349
Okay so let's set email equals self dot

00:05:41.349 --> 00:05:47.620
normalize underscore email email

00:05:47.620 --> 00:05:49.250
so we have our normalized email

00:05:49.250 --> 00:05:56.949
address next we will create our user
model by typing user equals self dot model

00:05:56.949 --> 00:06:03.220
email equals email and name equals name

00:06:03.220 --> 00:06:05.240
now what this does is it creates a new

00:06:05.240 --> 00:06:12.680
model that the user manager is
representing so by default self dot model is

00:06:12.680 --> 00:06:18.529
set to the model that the
manager is for and then it will create a

00:06:18.529 --> 00:06:23.580
new model object and set the email and
the name

00:06:23.580 --> 00:06:24.740
Next we're going to set the

00:06:24.740 --> 00:06:28.849
password and we can't just pass the
password in here as a clear text value

00:06:28.849 --> 00:06:35.750
we need to use the set password function
that comes with our user model so it's

00:06:35.750 --> 00:06:42.340
part of the abstract base user
and we set this by doing user dot set

00:06:42.340 --> 00:06:48.470
password password and pass it in like
that the reason we do that is so the

00:06:48.470 --> 00:06:53.090
password is encrypted we want to make
sure the password is converted to a hash

00:06:53.090 --> 00:06:58.220
and never stored as plain text in the
database because this way if somebody

00:06:58.220 --> 00:07:02.810
should manage to hack the database and
retrieve all the users they would only

00:07:02.810 --> 00:07:06.080
be able to see the hashed passwords
which means they wouldn't be able to

00:07:06.080 --> 00:07:11.630
convert that password to a clear text
password and then potentially use that

00:07:11.630 --> 00:07:16.940
to log into the users other services if
they used the same password for Facebook

00:07:16.940 --> 00:07:19.660
or another website for example

00:07:19.660 --> 00:07:21.890
They
could technically reverse-engineer it

00:07:21.890 --> 00:07:25.790
eventually if they'd given it enough
time so it doesn't mean you don't have

00:07:25.790 --> 00:07:29.900
to protect your database but it's the
best practice for storing any sensitive

00:07:29.900 --> 00:07:34.880
data in the database is to encrypt it
and by default Django does this with the

00:07:34.880 --> 00:07:37.980
set password function

00:07:37.980 --> 00:07:41.480
Okay now we can
save the user model so type user dot

00:07:41.480 --> 00:07:48.350
Save and then the standard is to specify
the database that you want to use so

00:07:48.350 --> 00:07:52.880
Django can support multiple databases
and we're only going to be using one database

00:07:52.880 --> 00:07:58.100
but it's best practice to add this line
anyway just to make sure that you

00:07:58.100 --> 00:08:03.380
support multiple databases in the future
if you should at it so type using equals

00:08:03.380 --> 00:08:07.740
self dot underscore DB

00:08:07.740 --> 00:08:12.560
Again this is the standard Django basically the standard

00:08:12.560 --> 00:08:16.820
procedure for saving objects in Django
and this is described in the Django

00:08:16.820 --> 00:08:20.820
documentation which I'll link in the
resources of the video

00:08:20.820 --> 00:08:21.620
Alright now we

00:08:21.620 --> 00:08:26.180
can return the user so after we create
the user we're going to return the newly

00:08:26.180 --> 00:08:31.620
created user object so type return
user

00:08:31.620 --> 00:08:33.560
and that is our create user

00:08:33.560 --> 00:08:35.300
function

00:08:35.300 --> 00:08:39.560
ok the next function we need to
create is the create super user function

00:08:39.560 --> 00:08:44.600
and this will use our create user
function to create a new user but also

00:08:44.600 --> 00:08:49.220
assign a super user status so it's an
admin user in the system

00:08:49.220 --> 00:08:55.800
So create a new function def create
super user and we're going to pass in the

00:08:55.800 --> 00:09:01.860
argument self email name and password
we're not going to allow the password to

00:09:01.860 --> 00:09:06.750
be non in this one because we want all
super users to have a password and then

00:09:06.750 --> 00:09:15.380
we will add a docstring create and save
a new super user with given details

00:09:15.660 --> 00:09:21.380
Ok now we will use the create user function
to create a user so we'll just do user

00:09:21.389 --> 00:09:28.290
equals self dot create underscore user
actually it is not an underscore there so

00:09:28.290 --> 00:09:33.380
self dot create user and open brackets

00:09:33.380 --> 00:09:38.120
we will pass in email address name and

00:09:38.120 --> 00:09:40.880
password

00:09:40.880 --> 00:09:44.279
So it might seem a bit
confusing here because we have self here

00:09:44.279 --> 00:09:49.850
we didn't pass self in self is
automatically passed in for any class

00:09:49.850 --> 00:09:54.360
functions so when you call it from a
different function or a different part

00:09:54.360 --> 00:09:58.259
of the code you don't need to specify
self because it gets automatically

00:09:58.259 --> 00:10:03.620
passed in when you call the function
this is part of Python

00:10:03.620 --> 00:10:05.220
Okay now that we

00:10:05.220 --> 00:10:10.610
have the user in our super user function
we're going to assign is super user to

00:10:10.610 --> 00:10:18.420
equals true so user dot is super user
equals true and then we'll set

00:10:18.420 --> 00:10:25.110
staff equals true so user dot is staff
equals true and then we will save our

00:10:25.110 --> 00:10:35.149
user model user dot save and again we'll pass in using equals self DB and return

00:10:35.540 --> 00:10:37.760
user

00:10:37.760 --> 00:10:43.040
Okay if you're a bit confused as to
where these is super user and is staff

00:10:43.040 --> 00:10:48.120
items came from then that's because we
didn't actually specify...well

00:10:48.120 --> 00:10:52.649
we did specify is staff but we didn't specify is super user in our user model because

00:10:52.649 --> 00:10:56.380
it automatically is created by the
permissions mixin

00:10:58.040 --> 00:10:59.960
Okay now we can save

00:10:59.970 --> 00:11:04.290
the models dot py and that's all we need to do to create our

00:11:04.290 --> 00:11:07.819
user model manager

