使用 get_user_model vs setings.AUTH_USER_MODEL 的 Django

阅读 Django 文档:

Get _ user _ model ()

您应该引用用户,而不是直接引用 User 使用 django.Contrib.auth.get _ user _ model ()建立模型 返回当前活动的用户模型-自定义用户模型,如果有 指定,否则为“用户”。

当您定义到用户的外键或多对多关系时 模型,您应该使用 AUTH _ USER _ MODEL 指定自定义模型 设定。

我对上面的文字感到困惑。我应该这样做吗:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

或者这个。

author = models.ForeignKey(get_user_model())

两者都有效。

95004 次浏览

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

get_user_model不能保证 User模型已经加载到应用程序缓存中。它可能在您的特定设置中工作,但它是一个碰运气的场景。如果你改变一些设置(例如 INSTALLED_APPS的顺序) ,它很可能中断导入,你将不得不花费额外的时间来调试。

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

如果未设置 AUTH _ USER _ MODEL,则回退到默认用户模型的方法:

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


USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', User)

姜戈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!
...
)

因为 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
)

settings.AUTH_USER_MODEL返回一个字符串(User 模型的位置) ,例如 user_accounts.User

get_user_model()返回 ACTUAL 模型类,而不是字符串。

因此,在需要 User 模型的情况下,使用 get_user_model()。如果需要它的位置(module.model作为字符串) ,请使用 settings.AUTH_USER_MODEL

正如我从《姜戈3. x 的两勺》一书中读到的 使用 get _ user _ model () :

这很糟糕,因为它往往会产生导入循环。

不好的例子: Owner = model. OneToOneField (get _ user _ model ())-> BAD DO NT DO IT