Getting the most out of Django’s User Model by Julia M. Looney

This video features Julia M. Looney at DjangoCon US 2017 in Spokane, Washington, USA.

Getting the most out of Django’s User Model by Julia M. Looney
0:23:44
Published September 7, 2017
1,546 views

DjangoCon US 2017 - Getting the most out of Django’s User Model by Julia M. Looney

Django’s User model is nice, but the fields it provides out of the box are minimal. We frequently need to associate our own custom data with a user, and luckily Django provides ways for us to add to its built-in User model. This talk will help novice Django developers understand which options are best when it comes to getting the most out of the Django User model.

I’ll start by talking about the built-in Django User model and what it has to offer.

Then I will identify scenarios when the User model might not be enough for a project, and why someone might want something with more flexibility. Then we’ll look at the different ways to get the most out of the Django User model. There are two main methods I’ll cover:

Extending the User model
Creating a custom User model

Extending the User model:

Extending the User model is handy when you only need to add a few extra fields. There are two main ways to do this: using a proxy model, and using a OneToOneField. I will cover the pros and cons of each, and give examples for implementing each.

Creating a custom User model:

With this method, you can substitute Django’s default User model with your own. Though more complex, a custom User model is particularly useful when you need to uniquely identify users by email address instead of by username. I’ll go into a couple more scenarios where a custom User model would be helpful, and show examples of implementation.

Lastly, I will show how each method works with the default Django admin, and how they can be managed there.

This talk was presented at: https://2017.djangocon.us/talks/getting-the-most-out-of-djangos-user-model/

LINKS:
Follow Julia M Looney 👇
Github: https://github.com/jlooney/

Follow DjangCon US 👇
https://twitter.com/djangocon

Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/

Summary

Julia M. Looney explains how Django’s built-in user model can be extended or replaced according to an application’s needs. Proxy models add methods or managers without changing the database; a one-to-one profile model adds fields in a separate table; and a custom model based on `AbstractBaseUser` supports changes such as using email instead of username, custom permissions, validators, and required fields. She stresses that custom users and profile relationships are easiest to introduce at the start of a project, and reviews the extra managers, forms, admin setup, migrations, and synchronization concerns each approach involves.

Key takeaways

  • A proxy model is suitable for adding methods, managers, or behavior without creating a database table or migration.
  • A one-to-one profile model adds custom user fields in a separate table, but requires handling profile creation, deletion, updates, and admin integration.
  • A custom user model based on `AbstractBaseUser` provides the most control, including email-based login, custom fields, permissions, and validators.
  • Set `AUTH_USER_MODEL` when replacing Django’s default user model and provide the required user manager and admin form.
  • Create custom user and profile models at the beginning of a project whenever possible, because changing them later can require difficult migrations and data work.

Summarised automatically from the transcript.

Transcript

3,496 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:14

Speaker 1: So hello everyone. Thank you for coming. My name is Julia Lena and I am a software engineer at the University of Texas. in Austin and today I'm going to talk to you about something that I've had to deal with a bit in my daily job which is getting the most out of gang So let's start out by first talking a bit about what the user model is. So it's part of Django's authentication system. And so that is set up for you automatically 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 it. your app and that

0:59

Speaker 1: is also set up automatically for you uh when you make your first migration and so it's really convenient and um out of the box The Dangle provides us with some some great attributes and functionality of the general. So it automatically gives us things like username, password, email, first name, last name. 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. So it's really great. But uh we often want a little bit more.

1:46

Speaker 1: Uh so although Dingo does provide us some really nice things out of the box We often want some a little bit more out of it. So we might want custom fields or custom permissions, custom model manager, or we can an alternative identifier to usernames. 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 to see why we might even want to customize the So here's our example app.

2:33

Speaker 1: It's a blog where users can make posts and leave comments and that sort of thing. And so because users are absolutely kind of an important part of this app 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. And I'll explain a bit what exactly a proxy model is. But this option It's really good if you just need to modify a few select things and it requires at least a amount of steps. And this is mostly due to the fact that it does not actually do any changes to the database.

3:19

Speaker 1: And so this is kind of a way of extending the existing Django user model so that we can just add a few additional things. 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 model user model trying to get around it. And so this quite 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 pressive user model. And so with this we would just be totally replacing

4:04

Speaker 1: the one that Django had to provide 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 or even if you want to add validators to your user model. So to get an idea of when we 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. And if we look at the post-it by section, we can see that things maybe aren't quite how we want them to be. So by default,

4:50

Speaker 1: Django will display a user's. username instead of their real name. And so in order for us to display their real name, we had to type out something like user. first name, user. last name. And sure, I mean that's that's possible, but it's kind of cumbersome and you 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? 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

5:35

Speaker 1: this is really good if you just want to add custom methods or custom model manager to your uh user called. Um so like I mentioned this 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. And so this means we can't add additional attributes or anything 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, the first thing we're going to do is just create a menu model that inherits

6:25

Speaker 1: 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, hey, look, I created this author model. It's actually just another name. for the user model. So these are the users like the user model. And so then from there, all we have to do is start our festivation. So considering our example again, we wanted to display users' world name instead of their user. So in this case we're gonna set up the dender string function to our alter class and so we can have it return the user's first name

7:10

Speaker 1: and instead of their username. And so yeah, that's pretty cool. So from uh from here, obviously you can add additional methods or model managers. Or, you know, something like that. 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 username. So we can see exactly who posted, and we don't have to worry about embarrassing usernames or anything like that. So obviously the proxy model, although it's kind of it's pretty useful and it's really easy to set up, it can also be pretty limited since we're not actually changing the database.

7:58

Speaker 1: at all. So let's talk about our next scenario where we might need a little bit more. So say we want to have user profiles for our log app. So what would a profile look like if we just used Django 's you know basic user model? So here's my profile. As you can see, with uh Django 's basic attributes, we wouldn't have a very interesting profile within the basic Of course. So what if we want our users to be able to add like a description of themselves or even like their location or you know whatever? In that case, we would have to

8:43

Speaker 1: you know make we had to modify the user model so that we have some additional attributes saved 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? 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 dation in a second. But this is really good for adding this and feature. because essentially we're creating that new model that will hold all of those additional attributes for that user. And so it's really it's a really convenient way of linking those two things together.

9:30

Speaker 1: So this can also do everything that the proxy model did. However, it does actually create a new database table, and so that means we're going to have to keep track of those migrations and all the lovely data stuff that comes along with making the model. And it does also require a few additional steps in order to make that relationship go smoothly throughout your entire hour. So let's take a look at how this would be uploaded. 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

10:15

Speaker 1: that has a one one field relationship with Django's user model. 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 would say before, we essentially create like a bucket to hold all these additional attributes for this particular user. 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

11:03

Speaker 1: user. personame But if we wanted to get something from our profile, all we would 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. 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. 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.

11:54

Speaker 1: And we also might want to include those additional attributes we added to the Django admin page. And so all these things might sound a little bit doctrine for maybe a beginner, which is kind of doctrine myself, but uh fortunately Django has some really nice documentation for how to do a line. these things. In particular the Django Admin part, they have a just emphasis on their documentation for how you can set up these things and make sure that you're considering So with all of these great things set up, we will have a much more interesting profile with our lovely new attributes. So yeah, that's it's great. So However, moving out to scenario three.

12:42

Speaker 1: We've had some complaints from our users. When they go to login, 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 your email address instead. So this would mean that users were identified by their email and say they were using them. 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 user model. So again, this might sound a little daunting, but fortunately Django has expected that we might want to do this.

13:27

Speaker 1: So they have left us with this lovely abstract class called abstract base user. And this provides the basic user implementation in password handling and all that kind of great stuff that we really don't want to mess with. So all we have to do is fill in the gaps for what it did provide us. And so like this, we would simply make a new model again inheriting from the abstract basing surface. From here we can go about our usual business, put in all the great attributes that we wanted in our app. But there's there's one thing that we definitely have to make sure that we do.

14:13

Speaker 1: This is something that the Abstract Base user class expects us to provide, which is the username field. And so obviously in the default 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 it'd be best if we have users log in with their email instead. So that's 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. Set the off-user model value to whatever our custom user model is.

15:04

Speaker 1: 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 model man or a user manager And so this will allow you to define functions for how users and super users are created. And you will also need to set up a form for for us to be able to modify our custom user in the Django ad And so this this does sound a little bit daunting again, but

15:49

Speaker 1: fortunately has our bats, and they have provided ways for us to do this in the the Django documentation. In fact, they've even provided fully implemented code examples that we can just copy and paste right into our project, or we should take the time to customize those if we want. So they make it pretty, you know, they they make it as easy as possible for us to make whatever customizations we need here And so, but 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 to do it at the very beginning of your

16:37

Speaker 1: project because that that can be huge pay. I also advise that if you'd like to create a profile model or the one-to-one relationship model that 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 it'll just be a trust me it'll be a very unpleasant situation. So just keep that in mind when you create your next project. It's not impossible to do it with anything. It's advisable to do it at the beginning. So hopefully now I have uh given you some great ideas of how you can customize

17:22

Speaker 1: your usual model and hopefully now you might even feel less intimidated to poke around and do whatever you want for the usual model. just to kind of recap. The proxy model is good if you just need to add a few methods. And that's also that's that's great at any time for a project all quite 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 using the abstract-based user model

18:09

Speaker 1: to make things a little bit easier. And so really the main point that I hope we take away from this is knowing which option to use. And so if you want to reference any of the documentation that I have talked about, I made a Git repo that in the README you'll find a bunch of links to the Django documentation. You can also email me with questions if you have questions. And I'm not really a Twitter person, but the other day I had to make one for a tutorial. So now I guess. So thank you

19:00

Speaker 2: Um so as you were thinking about writing this talk, what really inspired you you like what experience did you have either at work or in an open source project that helped you think this is what I want to share with a room people.

19:15

Speaker 1: Yes, that's thank you. That's a good question. Yeah, so um I work for the University of Texas and we really care what department you're in So we needed to know what department you were in in order to see certain pages on our app. And so I wanted to save that to our user model so we didn't have to like look at up every single time the user logged in. And 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 who logged in and I could set up the thing I to set up with greater pieces.

20:00

Speaker 1: And so it was it's kind of a trial and error sort of thing. But in that situation I set up Happy project and it was kind of But that's a disaster. Recommend doing SDA.

20:14

Speaker 3: Have you ever had the situation of having to deal with custom groups and say group profiles and have you found the uh there to be uh analogous methods means for modifying groups just like users?

20:28

Speaker 1: I haven't done a lot with groups I mean we we create our own groups that we associate with a bit, but I haven't really delved into customizing groups a whole lot. But I'm sure it's sure it's pretty similar. I'm sure it's

20:47

Speaker 4: We've long been interested in moving to a custom user model, but have seen these some people talk about how difficult it is partway through the project when we've got a pretty big project. Can you describe some of the the hurdles or problems to look for, how to overcome that, to move to a customer custom user model in the middle of a project.

21:08

Speaker 1: So haven't actually had the fortunate experience of having to set up a custom user But I'd say, I mean, coming from not having that experience, because general advice, I'd say just you know use as much of what Django gives you as you can so use the abstract base user if you can and just try to Try to switch it out as seamlessly as you can. Sorry to refer to us, but uh I wish you the best of luck.

21:49

Speaker 5: You mentioned uh one of the reasons you wanted to go to a uh customer. model study uh we're we're able to save the departmental affiliation of various users. Um so how do you then deal with users whose departmental affiliation change.

22:02

Speaker 1: Right. So for that, and this might not be the greatest advice ever, so take it with a grain of salt. We set up a signal so that every time a user logs in, it checks our university directory. in pulls their department, it updates their department and has changed. So to kind of make it go not not be as terrible, we we have it so that it only saves obviously if it it's changed. So we just also hope that people don't change the promises actually. Yeah

22:44

Speaker 6: One thing that drives me crazy is the usernames could be case sensitive. What is have you experienced or what's your solution? Which one of these would you recommend for like like uh converting all username to lowercase or something just to keep standardization across your

23:00

Speaker 1: I think I think in order to make the username field truly case insensitive you'd have to go like a custom sort of yield. Yeah I think I think that might be And although I mean there is the whole like checking it everywhere to force it to be all overcase when you handle it or something like that. But I think really importantly that you have to set

23:27

Speaker 2: All right, thank you so much, Julia.

Questions this talk answers

What is Django’s user model, and what does it provide by default?

Django’s user model is the core of its authentication system and is created automatically. It provides fields such as username, password, email, first name, and last name, along with password handling, user creation, and admin integration.

Discussed at 0:14

When should I use a proxy model to customize Django’s user model?

Use a proxy model when you only need to add methods, change behavior, or provide a custom model manager without changing the database schema. It does not create a new table, so it cannot add fields that require migrations.

Discussed at 5:35

How can I add custom fields like a location or bio to Django users?

Create a separate profile model with a one-to-one relationship to Django’s user model, then store the additional fields on the profile. They can be accessed through expressions such as `user.profile.location`.

Discussed at 8:43

What extra work is needed when using a one-to-one profile model with Django users?

You need to manage the profile alongside the user: create it when a user is created, delete it when the user is deleted, and decide how updates and admin integration should work. Django’s documentation covers these patterns, including admin setup.

Discussed at 11:03

How do I create a custom Django user model that uses email instead of a username?

Define a model inheriting from `AbstractBaseUser`, set its `USERNAME_FIELD` to `email`, and configure `AUTH_USER_MODEL` in settings to point to it. You also need a user manager for creating users and superusers and a form for editing the model in the admin.

Discussed at 13:27

When should I create a custom Django user model or profile model?

Create either one at the beginning of the project whenever possible. Changing to a custom user model later can be very difficult, and adding a profile model late can leave existing users without profiles and require unpleasant data work.

Discussed at 16:37

Which Django user-model customization option should I choose?

Use a proxy model for a few methods or behavior changes, a one-to-one profile model for additional fields, and a custom user model based on `AbstractBaseUser` when you need complete control, such as different required fields, validators, permissions, or identifiers.

Discussed at 17:22

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from DjangoCon US