Django使用get_user_model与settings.AUTH_USER_MODEL

问题:Django使用get_user_model与settings.AUTH_USER_MODEL

阅读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())

两者似乎都起作用。

Reading the Django Documentation:

get_user_model()

Instead of referring to User directly, you should reference the user model using django.contrib.auth.get_user_model(). This method will return the currently active User model – the custom User model if one is specified, or User otherwise.

When you define a foreign key or many-to-many relations to the User model, you should specify the custom model using the AUTH_USER_MODEL setting.

I’m confused with the above text. Should I be doing this:

author = models.ForeignKey(settings.AUTH_USER_MODEL)

or this…

author = models.ForeignKey(get_user_model())

Both seem to work.


回答 0

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

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

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

Using settings.AUTH_USER_MODEL will delay the retrieval of the actual model class until all apps are loaded. get_user_model will attempt to retrieve the model class at the moment your app is imported the first time.

get_user_model cannot guarantee that the User model is already loaded into the app cache. It might work in your specific setup, but it is a hit-and-miss scenario. If you change some settings (e.g. the order of INSTALLED_APPS) it might very well break the import and you will have to spend additional time debugging.

settings.AUTH_USER_MODEL will pass a string as the foreign key model, and if the retrieval of the model class fails at the time this foreign key is imported, the retrieval will be delayed until all model classes are loaded into the cache.


回答 1

自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!
        ...
    )

New since Django 1.11.

Since Django 1.11 you can use get_user_model() in both cases! So if you don’t want to bother about it further, just take it.

“in both cases” means: if you need the user model for accessing its attributes, as well as if you want to define a ForeignKey/ManyToMany-relation.

From the changelog:

get_user_model() can now be called at import time, even in modules that define models.

so… is there still a reason to use settings.AUTH_USER_MODEL? Well, the docs still recommend the settings.AUTH_USER_MODEL (which is a string) for defining relations, but without giving an explicit reason. Might be beneficial for performance, but doesn’t seem to matter much.

Code example:

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

回答 2

从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
        )

Since Django 1.11, get_user_model() actually uses 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
        )

回答 3

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

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

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

settings.AUTH_USER_MODEL returns a string (the location of the User model) e.g. ‘user_accounts.User’

get_user_model() returns the ACTUAL model class, not a string.

So in cases where you need the User model, use get_user_model(). If you need it’s location (module.model as a string), use the settings.AUTH_USER_MODEL .


回答 4

如果未设置AUTH_USER_MODEL,则可以回退到默认用户模型:

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

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

A way to fallback to the default user model if AUTH_USER_MODEL is not set:

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

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