What's up with Django's Custom User Model?

Do you want the users of your app to be able to login via email? Or would you like to add custom fields about your users? You might need a custom user model for that. But does it mean to use a custom user model?

In general, Django’s user models have to do with authentication and storing data about users. When you start a default Django project, your project is configured to use the default user model.

The default user model makes it possible for users to log in to your site using a username and password. You get user-related functionality such as limiting access to some parts of the site to authenticated users and the admin functionality for free.

Let’s look at when the default approach is not enough, and how it can bite you.

The limits of the default user model

The user model is designed so users can login via username and password.

You users won’t be able to login with email and password for example if you stick with the default user model. You also can’t add new fields to the default user model.

Solution: storing data about a user

If all you want to do, is store data about a user which is not relevant to the authentication process, you might want to look into the “Profile” model approach using another model and a one-to-one user model field.

This is a very good way to store data which is not needed for logging in, nor all the time in your Django code. However…

Why you really should go with a custom user model

Is it even remotely possible that you’ll want to:

  • Add a field to the user model, instead of a profile?
  • Modify the login behaviour to let users log in differently, for example via an email and password combination?

Then you should start your project using a custom user model. The docs state:

If you’re starting a new project, it’s highly recommended to set up a custom user model, even if the default User model is sufficient for you.

That’s because changing the user model after your project has been deployed to production and users have started using it is really tough and nasty business.

Using a custom user model

It’s hard to switch a user model out for another once your project is deployed and being used by real users. The problem is with migrating data and how Django works. If you’re still in early development you’ll be able to fix this however!

The Django docs have a very clear and nice section on this.

Basically you create a new app for your user data, extend AbstractUser, point the AUTH_USER_MODEL settings variable to the new model and you’re done.

What’s the difference between AbstractUser and AbstractBaseUser?

You can see the difference in the Django codebase:

If you know that you’re fine with Django’s default login behaviour, start with AbstractUser. It’s compliant with the admin and works out of the box. That’s how django-cookiecutter (a nifty template for starting new projects) uses this approach.

If you want to modify the login behaviour - for example to let users log in via email, you should go with extending the AbstractBaseUser. You can see a very nice example of this in the Django docs.

In Conclusion

If you’re starting a new project, you should switch to a custom user model right away. The Django docs are very clear about that, and it’s not much effort. Check out the official instructions on this topic.

It will save you from being inflexible or having to invest a lot of effort into a switch after the project is deployed and in active use.

Using the AbstractUser method, is probably the right way to go. If you want to save user-related data which is not relevant for login purposes, consider also using a “Profile” model approach.