【问题标题】:Django using get_user_model vs settings.AUTH_USER_MODELDjango 使用 get_user_model 与 settings.AUTH_USER_MODEL
【发布时间】:2014-08-29 01:31:43
【问题描述】:

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

两者似乎都有效。

【问题讨论】:

    标签: python django


    【解决方案1】:

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

    get_user_model 不能保证 User 模型已经加载到应用缓存中。它可能适用于您的特定设置,但这是一个偶然的情况。如果您更改某些设置(例如INSTALLED_APPS 的顺序),很可能会破坏导入,您将不得不花费额外的时间进行调试。

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

    【讨论】:

    • 具体来说,您可能会遇到 models.ForeignKey(get_user_model()) 的循环导入问题
    • This section of the docs 说“一般来说,您应该在导入时执行的代码中使用 AUTH_USER_MODEL 设置引用用户模型。get_user_model() 仅在 Django 导入所有模型后才有效。”
    • 所以具体来说,在函数(视图、模型/序列化器/表单方法)中,使用get_user_model(),对于类属性使用AUTH_USER_MODEL
    【解决方案2】:

    自 Django 1.11 以来的新功能。

    从 Django 1.11 开始,您可以在这两种情况下使用 get_user_model()!因此,如果您不想再为此烦恼,那就接受吧。

    “在这两种情况下”意味着:如果您需要用户模型来访问其属性,以及如果您想定义 ForeignKey/ManyToMany-relation。

    来自the changelog

    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 定义外键和多对多关系
    • 感谢您指出此建议,不知为何我在写回复时忽略了它,但现在我找到了。我试图将其整合到答案中(仍然偏爱get_user_model,尤其是对于对区别感到困惑的读者)
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • 你能解释一下它的位置是什么意思吗?它所属的应用程序还是它所属的用户?
      • 位置是指路径
      【解决方案5】:

      在未设置 AUTH_USER_MODEL 时回退到默认用户模型的方法:

      from django.conf import settings
      from django.contrib.auth.models import User
      
      USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', User)
      

      【讨论】:

      • AUTH_USER_MODEL 已经有一个默认值,所以它会一直设置。
      • settings.AUTH_USER_MODEL 也是一个字符串,你的后备 User 是一个模型
      猜你喜欢
      • 1970-01-01
      • 2021-01-04
      • 2012-12-22
      • 1970-01-01
      • 2018-10-15
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      • 2019-09-30
      相关资源
      最近更新 更多