You Probably Don’t Need Django’s get_user_model()

Which way to the User model?

Django’s authentication system, django.contrib.auth, provides a built-in User model class. You can swap this to a different class with the AUTH_USER_MODEL setting, most easily at the start of the project.

django.contrib.auth also provides a function called get_user_model(). This retrieves the current user model class, whether it is the built-in one or a swapped one. You can use this function like so:

from django.contrib.auth import get_user_model

User = get_user_model()


def some_function():
    for user in User.objects.all():
        ...

But in most Django code, you do not need to use get_user_model(), and you can instead use a vanilla import:

from example.core.models import User


def some_function():
    for user in User.objects.all():
        ...

A vanilla import has several advantages;

get_user_model() is intended for use in reuseable Django apps, such as those you install from PyPI. Such apps cannot know what the user model class is, so they need to use get_user_model() to refer to it. Within a project, where you know what your user model class is, you can directly import it. Internally, get_user_model() performs an import of the path in the AUTH_USER_MODEL setting.

I’ve seen a bunch of projects unnecessarily use get_user_model() throughout their code. I think it may be due to this description in the function’s documentation:

Instead of referring to User directly, you should reference the user model using django.contrib.auth.get_user_model().

Alone, this sentence seems to encourage always using the function. But it appears in the context of making code reusable between different projects. Since most code only lives in one project, it doesn’t need get_user_model(). If you later need to extract some code into a reusable app, it’s not much work to change its imports at that point.

Some might consider using get_user_model() in case they need to change AUTH_USER_MODEL. Since changing user model mid-project is quite complicated, I would say “YAGNI” (You Ain’t Gonna Need It) to that. If you change your user model, updating imports will be the least of your concerns.

Fin

May your code be ever simpler,

—Adam


Learn how to make your tests run quickly in my book Speed Up Your Django Tests.


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: