Getting the most out of Django’s User Model
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Part Number | 27 | |
Number of Parts | 48 | |
Author | ||
Contributors | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/33188 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
DjangoCon US 201727 / 48
2
5
6
14
16
23
26
30
31
32
34
39
43
48
00:00
Model theoryFatou-MengeAttribute grammarPasswordEmailField (computer science)Data modelBlogTime evolutionProcess (computing)Level (video gaming)MathematicsComputer configurationProxy serverPatch (Unix)Shape (magazine)Dean numberDatabaseMeta elementVarianceFamilyInternetworkingComplex numberRevision controlExecution unitGradientTable (information)Game theoryWeightMultiplication signGroup actionRight angleSheaf (mathematics)AreaMereologyInterior (topology)WordEndliche ModelltheorieCASE <Informatik>ResultantProxy serverValidity (statistics)Mobile appOrder (biology)QuicksortAliasingMathematicsData managementAdditionComputer configurationType theoryDatabaseAttribute grammarMeta elementIdentifiabilitySuite (music)BitHuman migrationFunctional (mathematics)Field (computer science)System administratorPasswordBlogForm (programming)AuthenticationPhysical systemProjective planeCore dumpSocial classAuthorizationMachine visionElectronic visual displayReal numberString (computer science)Computer animation
07:52
EmailComputer configurationField (computer science)TrailData modelModel theoryFatou-MengeLetterpress printingUser profileInclusion mapMaizeData typeBlogLoginImplementationPasswordForm (programming)TheoryExecution unitEndliche ModelltheorieCartesian coordinate systemInsertion lossFood energyGroup actionMultilaterationOffice suiteRight angleStudent's t-testSoftware testingAreaPower (physics)Attribute grammarDatabaseTrailEmailProfil (magazine)Field (computer science)AbstractionSocial classAuthorizationData managementFunctional (mathematics)Inheritance (object-oriented programming)Form (programming)BijectionComputer configurationWeb pageBitImplementationSubject indexingMobile appAddress spaceDescriptive statisticsPositional notationPasswordTable (information)AdditionSet (mathematics)Order (biology)Multiplication signUser profileDefault (computer science)System administratorComputer animation
15:44
Proxy serverData modelField (computer science)Online helpModel theoryInformation securityDifferent (Kate Ryan album)AreaMultiplication signWordLevel (video gaming)Universe (mathematics)MathematicsTheoryEvent horizonCASE <Informatik>Variety (linguistics)GradientRight angleEndliche ModelltheorieDisk read-and-write headForm (programming)Group actionMobile appLoginDirectory serviceProxy serverSensitivity analysisStandard deviationField (computer science)Order (biology)AbstractionView (database)Computer configurationBijectionError messageTwitterQuicksortProjective planePoint (geometry)Link (knot theory)Profil (magazine)CodeMehrplatzsystemLecture/Conference
23:35
XML
Transcript: English(auto-generated)
00:35
So let's start out by first talking a bit about what the user model is.
00:41
So it's part of Django's authentication system. And so that is set up for you to learn, I believe, when you create your project. And the user model is kind of the core of Django's authentication system. And it represents the people who will be using your app. And that is also set up automatically for you when you make your first migration.
01:04
And so it's really convenient. And out of the box, Django provides us with some great attributes and functionality of Django. So it automatically gives us things like username, password, email, first name, last name.
01:21
And it also provides us with all of the functions and everything needed to create users and handle passwords and all that sort of stuff. So it's really nice and convenient. And it even gives us a nice form on the Django admin to edit users and all that sort of thing.
01:41
So it's really great. But we often want a little bit more. So although Django does provide us some really nice things out of the box, we often want a little bit more out of it. So we might want custom fields, or custom permissions, custom model manager,
02:01
or an alternative identifier to username. And so fortunately, Django kind of has expected that we want more. And it has provided us with several different ways that we can customize the user model to best suit our app. So before I go over these options, let's start by looking at an example app
02:26
to see why you might even want to customize the user model. So here's our example app. It's a blog where users can make posts and leave comments and that sort of thing. So because users are absolutely an important part of this app,
02:45
we want to customize the user model as much as we can to kind of get the most out of it and make our app run as smoothly as possible. So let's go through our options. So our first option for customization is to use a proxy model.
03:00
And I will explain a bit what exactly a proxy model is. But this option is really good if you just need to modify a few select things. And it requires at least a ton of steps. And this is mostly due to the fact that it does not actually do any changes to the database. And so this is kind of a way of extending the existing Django user model
03:26
so that we can just add a few additional things to it. Our second option is to create a new model that has a one-to-one relationship with the user model. So again, we're just extending the existing user model, trying to get around it.
03:44
And so this requires a few more steps. But this will allow us to add things like more attributes to our users. And so our third option that I'll be covering is to just completely create our own custom user model.
04:01
And so with this, we would just be totally replacing the one that Django had provided us out of the box so that we could just have more freedom. And so this is really good when you need different required fields or when you need custom permissions or even if you want to add validators to your user model.
04:22
So to get an idea of when we would use each of these options, that's really kind of key. Let's go through a few scenarios for each of these. So let's take a look again at our great app. So here's a post from our popular blog app.
04:43
And if we look at the posted by section, we can see that things maybe aren't quite how we want them to be. So by default, Django will display a user's username instead of their real name. And so in order for us to display their real name,
05:01
we had to type out something like user.firstname, user.lastname. And sure, I mean that's possible, but it's kind of cumbersome and we might forget that sort of stuff. So fortunately, we can easily customize the user model to take care of this. And for that we will use our first option, which is the proxy model. So what exactly is a proxy model?
05:22
It is really kind of a way of creating an alias for an existing model that you can add methods to. And so it's not actually going to make changes to the database. And so this is really good if you just want to add custom methods or a custom model manager
05:41
to your user model. So like I mentioned, this doesn't actually create a new table or anything like that in the database. And so you're limited to just things that would not require a migration.
06:00
And so this means we can't add additional attributes or anything like that. But it is useful when all we need to do is add custom methods or override one of the existing user methods. So let's take a look at how this would be implemented. So to set up a proxy model for the user model,
06:22
the first thing we're going to do is just create a new model that inherits the user model. And then all we need to do is set up the meta class where we set proxy to true. And so this just tells Django that, hey, look, I created this author model. It's actually just another name for the user model.
06:41
So these are users like the user model. And so then from there, all we have to do is start our custom vision. So considering our example again, we wanted to display users real name instead of their user name. So in this case, we're going to set up the Django string function to our author class.
07:07
And so we'd have it return the user's first name instead of their user name. And so that's pretty cool. So from here, obviously you can add additional methods or model managers or something like that.
07:27
So going back to our example app, we can now see that in our lovely blog post here, we can see the user's name instead of their user name.
07:40
So we can see that can be posted. And we don't have to worry about embarrassing user names or anything. So obviously the proxy model, although it's pretty useful and it's really easy to set up, it can obviously be pretty limited since we're not actually changing the database at all. So let's talk about our next example where we might need a little bit more.
08:05
So say we want to have user profiles for our blog app. So what would a profile look like if we just used Django's basic user model? So here's my profile.
08:23
As you can see with Django's basic attributes, we wouldn't have a very interesting profile within the picture of course. So what if we want our users to be able to add a description of themselves or even their location or whatever.
08:41
In that case, we would have to modify the user model so that we have some additional attributes that stay for each user. And so for that, we will use our option two, which is to set up a one-to-one relationship. So what does this mean?
09:00
It means that we're going to create a new model that has a one-to-one relationship with the user model. And I'll show the positioner in a second. But this is really good for adding custom fields because essentially we're creating that new model that will hold all of those additional attributes for that user.
09:23
And so it's a really convenient way of linking those two things together. So this can also do everything that the proximal did. However, it does actually create a new database table. And so that means we're going to have to keep track of those quitions
09:42
and all of the lovely database stuff that comes along with making the model. It does also require a few additional steps in order to make that relationship go smoothly throughout your entire app. So let's take a look at how this would be implemented.
10:01
So to set up this one-to-one relationship, we start again by creating a new model. This time it's just a regular model. We're going to call it profile. And so within the profile model, we will create a user attribute that has a one-to-one field relationship with Django's user model.
10:22
And so this means that every user will have one profile and every profile will be associated with one user. And so with this great relationship set up, we can start by adding in all of the additional attributes that we wanted. And so this is, like I was saying before, we should actually create a bucket to hold all of these additional attributes for this particular user.
10:49
And accessing these attributes is actually pretty simple. It's almost just like accessing the attributes for the regular user model. So when we're just trying to get one of the default attributes, we'd say something like user.personing.
11:06
But if we wanted to get something from our profile, all we'd have to do is say something like user.profile.location. And so if we do user.profile, we can access any of those new attributes that we've added.
11:21
So as I mentioned before, there are some additional steps here. And so for our profile model to work smoothly, we'll have to consider setting up some of these things. So we need to consider the situations with creating new users. So when a new user is created, we'll also have to make sure that their profile is created.
11:43
And similarly, when a user is deleted, we'll have to make sure that their profile is deleted. We also might want to make sure that when a user's profile is updated, their user gets updated or vice versa. And we also might want to include those additional attributes we added to the Django admin page.
12:00
And so all these things might sound a little bit daunting for maybe a beginner. I thought I was kind of daunting myself. But fortunately, Django has some really nice documentation for how to do a lot of these things. In particular, the Django admin part, they have a post index on their documentation
12:21
for how you can set up these things and make sure that you're considering everything. So with all these great things set up, we will have a much more interesting profile with our lovely new attributes. So yeah, it's great. So here we have scenario three.
12:43
We've had some complaints from our users. When they go to log in, they can't remember the username that they used to sign up with. So to fix this, we decided that it would be best if users could log in with their email address instead. So this would mean that users were identified by their email instead of email.
13:04
But with the user model customization that we've done so far, we can't do that. So we need to move on to our option three, which is to create a custom email.
13:20
So again, this might sound a little daunting, but fortunately, Django has expected that we might want to do this. So they have left us with this lovely abstract class called abstract base user. And this provides the basic user implementation and password handling and all that kind of great stuff that we really don't want to mess with.
13:44
So all we have to do is fill in the gaps for what it didn't provide us. And so with this, we would simply make a new model again, inheriting from the abstract base user.
14:01
From here, we can go about our usual business, put in all the great attributes that we wanted in our app. But there's one thing that we definitely have to make sure that we do. And this is something that the abstract base user class expects us to provide, which is the username field.
14:20
And so obviously in the Django user model, the username field is username. But we don't want users to be identified by the username in our custom model. So we're going to set that field to email, because we decided that maybe that's if we can't use one email instead.
14:42
So that's really handy. And one thing we have to consider is we need to let Django know that we did override their user model. And so to do that, it's pretty simple. All we do is in our settings outline, we set the auth user model value to whatever our custom user model is.
15:05
And so as I mentioned before, there are some additional steps that we need to take care of with the abstract base user. So the main things are setting up a user manager.
15:25
And so this will allow you to define functions for how users and super users are created. And we will also need to set up a form for us to be able to modify our custom user in the Django app.
15:42
And so this does sound a little bit daunting again, but fortunately Django has our backs. And they have provided ways for us to do this in the Django documentation.
16:00
In fact, they've even provided fully implemented code examples that we can just copy and paste right into our project. Or we can take the time to customize those if we want. So they make it as easy as possible for us to make whatever customizations we need here.
16:20
And so once we take care of all of these things, we will have our very own custom user model. So before I move on, I would like to give a word of warning. If you do want to create a custom user model, I highly advise you do it at the very beginning of your project. Because that could be a huge pain.
16:43
I also advise that if you'd like to create a profile model or the one-to-one relationship model, then you also do that at the very beginning of your project. Because then if you don't, we'll have a bunch of users that don't have a profile. And it'll just be a very unpleasant situation.
17:06
So just keep that in mind when you create your next project. It's not impossible to do it with your first. It's valuable to do at the beginning. So hopefully now I have given you some great ideas on how you can customize your user model.
17:24
And hopefully now you might even feel less intimidated to poke around and do whatever you want for the user model. Just to kind of recap, the proxy model is good if you just need to add a few methods. And that's also great if you can do that any time through your project.
17:41
The one-to-one relationship option is really good if you want to add custom fields. It's advisable that you use it at the beginning of your project, not a disaster. There are some additional things you have to set up there to make sure that relationship is working smoothly throughout your app. And then if you just want complete customization, you can just replace Django's user model with your own
18:05
using the abstract base user model to make things a little bit easier. And so really the main point that I hope you take away from this is knowing which option to use for it.
18:22
And so if you want to reference any of the documentation that I talked about, I made a git repo, and in the readme you'll find a bunch of links to the Django documentation. You can also email me some questions if you have questions.
18:41
And I'm not really a Twitter person, but the other day I had to make one for Ricky Coro. So you can tweet me now I guess. But yeah. So thank you.
19:18
So I worked for the University of Texas, and we really care what department you're in.
19:25
For some of our apps. So we needed to know what department you're in in order to see certain views on our app. And so I wanted to save that to our user model so we didn't have to look it up every single time the user logged in.
19:41
So after doing some research, I discovered the one-to-one relationship option that I talked about. And that, it worked really great. So I was able to associate a department with every single user logged in, and I could set up the thing I needed to set up with a greater piece.
20:00
So it was kind of a trial and error sort of thing. But in that situation, I had set up an app with the project, and it was kind of messy. But that was a disaster. I recommend doing that for you. Have you ever had the situation of having to deal with custom groups, and say group profiles,
20:21
and have you found there to be analogous methods, means for modifying groups just like users? I haven't dealt a lot with groups. We create our groups that we associate with users a bit. But I haven't really delved into customizing groups a whole lot.
20:41
But I'm sure it's pretty similar. I'm sure it's pretty cool to work with you there. We've long been interested in moving to a custom user model, but have seen some people talk about how difficult it is. Can you describe some of the hurdles or problems to look for, how to overcome that, to move to a custom user model in the middle of the project?
21:08
So I haven't actually had the fortunate experience of having to set up a custom user in the middle of the project. I'd say, coming from not having that experience, just as general advice, I'd say just use as much of what Django gives you as you can.
21:32
So use the app track-based user if you can, and just try to switch it out as soon as you can.
21:41
Sorry to interrupt, but I wish you the best of luck. You mentioned one of the reasons you wanted to go to a custom user model was that you were able to save departmental affiliation of various users. So how do you then deal with users whose departmental affiliations change?
22:02
Right, so for that, and this might not be the greatest advice ever, we set up a signal so that every time a user logs in, it checks our university directory and pulls their department, it updates their department and it has changed.
22:25
So to kind of make it go, not be as terrible, we have it so that it only saves, obviously, if it's changed. So we just also hope that people don't change the problems.
22:40
Just to share with you once per session? Yes, essentially, yes. One thing that drives me crazy is that user names can be case sensitive. Have you experienced, which one of these would you recommend for converting all the user names to lowercase or something, just to keep standardization across? I think in order to make the user name feel truly case insensitive, you'd have to go with a custom sort of yield.
23:10
I think that might be the right way to go. Although there is the whole checking it everywhere to force it to be lowercase or something like that.
23:23
But I think really more too that you have to accept. Alright, thank you so much, Julia.