Django使用get_user_model与settings.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())

两者似乎都起作用。

Answers:


87

使用settings.AUTH_USER_MODEL会延迟实际模型类的检索,直到所有应用程序都加载完毕。get_user_model会在您首次导入应用程序时尝试检索模型类。

get_user_model无法保证User模型已经加载到应用程序缓存中。它可能会在您的特定设置中起作用,但这是一个命中注定的情况。如果您更改某些设置(例如的顺序INSTALLED_APPS),则很可能会中断导入,您将不得不花费更多的时间进行调试。

settings.AUTH_USER_MODEL 将传递一个字符串作为外键模型,并且如果在导入该外键时模型类的检索失败,则检索将被延迟,直到将所有模型类都加载到缓存中为止。


7
具体来说,您可能会遇到model.ForeignKey(get_user_model())的循环导入问题
Chris Clark

2
该文档的这一部分说:“一般而言,您应该使用AUTH_USER_MODEL在导入时执行的代码中的设置来引用User模型。get_user_model()只有在Django导入了所有模型后,该模型才起作用。”
Hamish Downer 2015年

7
因此,具体来说,在函数(视图,模型/序列化器/表单方法)中,use get_user_model(),对于类属性使用AUTH_USER_MODEL
尼克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,特别是对于那些对区分感到困惑的读者)
伊利亚(Ilja

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()返回ACTUAL模型类,而不是字符串。

因此,在需要用户模型的情况下,请使用get_user_model()。如果需要它的位置(module.model作为字符串),请使用settings.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
settings.AUTH_USER_MODEL也是一个字符串,您的后备User模型是一个模型
Matt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.