Django за допомогою get_user_model проти налаштувань. AUTH_USER_MODEL


98

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

get_user_model ()

Замість того, щоб звертатися безпосередньо до Користувача, слід посилатися на модель користувача за допомогою django.contrib.auth.get_user_model (). Цей метод поверне поточну активну модель користувача - користувацьку модель користувача, якщо вона вказана, або користувач інакше.

Коли ви визначаєте зовнішній ключ або відносини багато-до-багатьох до моделі користувача, вам слід вказати власну модель, використовуючи параметр AUTH_USER_MODEL.

Мене плутає вищенаведений текст. Чи повинен я робити це:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

або це ...

author = models.ForeignKey(get_user_model())

Здається, обидва працюють.

Відповіді:


87

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

get_user_modelне може гарантувати, що Userмодель вже завантажена в кеш програми. Це може працювати у вашому конкретному налаштуванні, але це сценарій невдалих помилок. Якщо ви зміните деякі налаштування (наприклад, порядок INSTALLED_APPS), це цілком може порушити імпорт, і вам доведеться витратити додатковий час на налагодження.

settings.AUTH_USER_MODEL передаватиме рядок як модель зовнішнього ключа, і якщо отримання класу моделі не вдасться під час імпорту цього зовнішнього ключа, отримання буде відкладено, поки всі класи моделі не будуть завантажені в кеш.


7
Конкретно, ви можете зіткнутися з круговими проблемами імпорту з моделями. ForeignKey (get_user_model ())
Кріс Кларк

2
У цьому розділі документів сказано: "Взагалі кажучи, ви повинні посилатися на модель користувача із AUTH_USER_MODELналаштуваннями в коді, що виконується під час імпорту. get_user_model()Працює лише після того, як Django імпортує всі моделі."
Хаміш Даунер,

7
Отже, конкретно, у функціях (подання, моделі / серіалізатор / методи форми), використовувати 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 () повертає АКТУАЛЬНИЙ клас моделі, а не рядок.

Тому у випадках, коли вам потрібна модель користувача, використовуйте get_user_model (). Якщо вам потрібно його розташування (module.model як рядок), скористайтеся налаштуваннями.AUTH_USER_MODEL.


-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
AUTH_USER_MODEL - це також рядок, а ваш резервний варіант User- модель
Matt
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.