Django has a powerful, built-in user authentication system that makes it quick and easy to add login, logout, and signup functionality to a website.
But how should a Django developer reference the User model? The official Django docs list three separate ways:
User
AUTH_USER_MODEL
get_user_model()
But I find the explanation given to be incomplete. So in this post we will review why you might need to reference the User model and the pros/cons of each approach.
Option 1: User
Let's assume we have a basic models.py
file for a Blog. Here's what it might look like:
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=50)
body = models.TextField()
Now what if we wanted to add an author
field so that we could track which user created a blog post and later add permissions on top of that?
The default way is to access User
directly, which is the built-in Django model that provides us with username
, email
, password
, first_name
, and last_name
fields.
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
body = models.TextField()
Pretty straightforward, no?
The problem is that we should always use a custom user model for new projects. The official docs even say so.
But if we have a custom user model, we cannot refer to it as User
so how do we reference it? It turns out there are two different ways.
Option 2: AUTH_USER_MODEL
The first--and until recently best--way to reference the custom user model was via AUTH_USER_MODEL.
To add a custom user to a new Django project you need to create a new user model and then set it as such in your settings.py
file. I wrote a separate post on how to do this.
But the takeaway is that if we made a users
app, a CustomUser
model within it, then to override the default User
model in our settings.py
file we would do the following.
# settings.py
AUTH_USER_MODEL = `users.CustomUser`
In our Blog models.py
file the code would look like this:
from django.conf import settings
from django.db import models
class Post(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
title = models.CharField(max_length=50)
body = models.TextField()
Using settings
we pass the AUTH_USER_MODEL
as a string into our model.
Option 3: get_user_model
A third way to access the user model is via get_user_model. Up until the release of Django 1.11, get_user_model
was not called at import time--meaning it would not always work correctly--however that has since been changed. It is therefore safe to use.
The code would look as follows:
# settings.py
AUTH_USER_MODEL = `users.CustomUser`
Then in our Blog models.py
file the code would look like this:
from django.contrib.auth import get_user_model
from django.db import models
class Post(models.Model):
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE
)
title = models.CharField(max_length=50)
body = models.TextField()
get_user_model()
will return the currently active user model: either a custom user model if specified or else User
. It is therefore a cleaner approach, in my opinion, because AUTH_USER_MODEL
only works if a custom user model is set.
Conclusion
The takeaway is that working with User models is tricky in any web framework. Django has a robust user authentication system but given that many projects use a custom user model instead, the best approach when you want to refer to the current user model--of the three available--is to just always use get_user_model
.