When working with Django, the User model is central to authentication and user data management. But there’s more than one way to reference it, and choosing the wrong method can lead to subtle bugs, especially if you ever switch to a custom user model. In this post, I’ll break down all the ways to reference the User model, explain their differences, and when to use each.
1. Direct Import of the Default User
from django.contrib.auth.models import User
user = User.objects.get(pk=1)
This approach is straightforward and works fine if you’re only ever using Django’s built-in User. However, it will break if you later swap in a custom user model. For this reason, it’s generally not recommended in reusable or production code.
2. Using get_user_model()
Django provides a utility function to retrieve the currently active user model:
from django.contrib.auth import get_user_model
User = get_user_model()
user = User.objects.get(pk=1)
- Returns: The actual user model class (default or custom).
- Use case: Runtime operations like querying users, creating instances, or type-checking.
- Pro tip: This is the recommended approach for runtime code in apps that might be reused with different user models.
3. Using settings.AUTH_USER_MODEL
When defining model relationships, the correct approach is to use a string reference to the user model:
from django.conf import settings
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
- Returns: A string like "auth.User" or "users.CustomUser".
- Use case: Model fields (
ForeignKey,OneToOneField,ManyToManyField). - Benefit: Avoids circular import issues and works seamlessly with custom user models.
4. String Literal in Model Fields
You can also use a direct string literal:
class Article(models.Model):
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE)
Or, for a custom user model:
class Article(models.Model):
author = models.ForeignKey(
'users.CustomUser',
on_delete=models.CASCADE)
Caution: Hardcoding auth.User makes your code less flexible if you later introduce a custom user model.
Top comments (2)
Really helpful breakdown. I've been guilty of importing
Userdirectly in a few places. After reading this, I'm going to standardize onget_user_model()for all runtime queries and usesettings.AUTH_USER_MODELin all my FK/OneToOne relations. I'll also scan my models for any hardcoded'auth.User'strings and replace them so I don't get burned later if I introduce a custom user model.Thanks bot