Django с использованием get_user_model и settings.AUTH_USER_MODEL

99

Чтение документации Django:

get_user_model ()

Вместо того, чтобы ссылаться на пользователя напрямую, вы должны ссылаться на модель пользователя с помощью django.contrib.auth.get_user_model (). Этот метод вернет текущую активную модель User - пользовательскую модель User, если она указана, или User в противном случае.

Когда вы определяете внешний ключ или отношения «многие ко многим» для модели User, вы должны указать настраиваемую модель с помощью параметра AUTH_USER_MODEL.

Меня смущает приведенный выше текст. Должен ли я делать это:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

или это...

author = models.ForeignKey(get_user_model())

Кажется, оба работают.

Прометей
источник

Ответы:

89

Использование settings.AUTH_USER_MODELзадержит получение фактического класса модели до тех пор, пока не будут загружены все приложения. get_user_modelпопытается получить класс модели в момент первого импорта вашего приложения.

get_user_modelне может гарантировать, что Userмодель уже загружена в кеш приложения. Это может сработать в вашей конкретной настройке, но это случайный сценарий. Если вы измените некоторые настройки (например, порядок INSTALLED_APPS), это может прервать импорт, и вам придется потратить дополнительное время на отладку.

settings.AUTH_USER_MODEL передаст строку в качестве модели внешнего ключа, и если получение класса модели завершится ошибкой во время импорта этого внешнего ключа, получение будет отложено до тех пор, пока все классы модели не будут загружены в кеш.

Knbk
источник
7
Конкретно, вы можете столкнуться с проблемами циклического импорта с моделями. ForeignKey (get_user_model ())
Крис Кларк,
2
В этом разделе документации говорится: «Вообще говоря, вы должны ссылаться на модель User с AUTH_USER_MODELнастройкой в ​​коде, который выполняется во время импорта. get_user_model()Работает только после того, как Django импортировал все модели».
Хэмиш Даунер,
7
Так что конкретно, в функциях (представления, методы модели / сериализатора / формы) use get_user_model(), для использования атрибутов класса AUTH_USER_MODEL?
Nick T
53

Новое с Django 1.11.

Начиная с Django 1.11, вы можете использовать get_user_model()в обоих случаях! Так что, если вы не хотите больше об этом беспокоиться, просто возьмите.

«в обоих случаях» означает: если вам нужна модель пользователя для доступа к ее атрибутам, а также если вы хотите определить отношение ForeignKey / ManyToMany.

Из журнала изменений :

get_user_model () теперь можно вызывать во время импорта даже в модулях, определяющих модели.

так что ... есть ли еще причина использовать settings.AUTH_USER_MODEL? Что ж, документы по-прежнему рекомендуют settings.AUTH_USER_MODEL(который является строкой) для определения отношений, но без явной причины. Может быть полезно для производительности, но не имеет большого значения.

Пример кода:

from django.db import models
from django.contrib.auth import get_user_model
...
    ...
    user = models.ForeignKey(
        get_user_model(),
        null=True, # explicitly set null, since it's required in django 2.x. - otherwise migrations will be incompatible later!
        ...
    )
Илья
источник
Спасибо, что указали, что это get_user_model()можно вызвать во время импорта; однако Django по-прежнему советует пользователям определять внешний ключ и отношения «многие ко многим» с помощью AUTH_USER_MODEL
kevins
2
Спасибо, что указали на эту рекомендацию, я как-то упустил ее из виду, когда писал ответ, но теперь нашел. Я попытался интегрировать это в ответ (все еще предпочитаю get_user_model, особенно для читателей, которые не понимают различия)
Илья
7

Начиная с Django 1.11, get_user_model()фактически использует settings.AUTH_USER_MODEL:

def get_user_model():
    """
    Return the User model that is active in this project.
    """
    try:
        return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
    except ValueError:
        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
    except LookupError:
        raise ImproperlyConfigured(
            "AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
        )
Мурей Тасрок
источник
0

settings.AUTH_USER_MODEL возвращает строку (расположение модели пользователя), например, user_accounts.User.

get_user_model () возвращает АКТУАЛЬНЫЙ класс модели, а не строку.

Поэтому в случаях, когда вам нужна модель User, используйте get_user_model (). Если вам нужно его местоположение (module.model в виде строки), используйте settings.AUTH_USER_MODEL.

ImportError
источник
-11

Способ возврата к модели пользователя по умолчанию, если AUTH_USER_MODEL не установлен:

from django.conf import settings
from django.contrib.auth.models import User

USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', User)
синхронизировать
источник
7
AUTH_USER_MODELуже имеет значение по умолчанию, поэтому оно всегда будет установлено.
Knbk
4
settings.AUTH_USER_MODEL - это тоже строка, а ваш запасной вариант User- это модель
Мэтт,