【问题标题】:Django 1.5: Accessing custom user model fields in models.pyDjango 1.5:访问 models.py 中的自定义用户模型字段
【发布时间】:2013-07-02 10:09:46
【问题描述】:

我正在开发一个 Django 1.5 项目,并且我有一个自定义用户模型(我们称之为 CustomUser)。另一个应用程序 (SomeApp) 需要引用此自定义用户模型。出于 ForeignKey 等的目的,Django 文档说要使用

User = settings.AUTH_USER_MODEL 

但是,SomeApp.models 中的某些函数需要访问以前称为User.objects 的内容。但是 User 现在是一个字符串而不是一个类,所以 User.objects 失败了。另一种选择是

from django.contrib.auth import get_user_model
User = get_user_model()

这在其他模块中有效,但是当我在 SomeApp 的 models.py 中使用它时,Django 会引发错误:

ImproperlyConfigured("AUTH_USER_MODEL 指的是尚未安装的模型 '%s'" % settings.AUTH_USER_MODEL)

有什么想法吗?

编辑 1 - 回溯:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "...\django-badger\badger\__init__.py", line 7, in <module>
    from badger.models import Badge, Award, Progress
  File "...\django-badger\badger\models.py", line 26, in <module>
    User = get_user_model()
  File "...\lib\site-packages\django\contrib\auth\__init__.py", line 127, in get_user_model
    raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)
ImproperlyConfigured: AUTH_USER_MODEL refers to model 'MyApp.AuthUser' that has not been installed

编辑 2 - INSTALLED_APPS 设置:

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'south',
'MyApp',   # this is where my user model is defined
'SomeApp', # I try to use get_user_model() in this app's models.py; doesn't work.
'social_auth',
)

【问题讨论】:

  • 你能发布完整的回溯吗?
  • 您是如何在设置中定义AUTH_USER_MODEL 的?用户在哪个应用程序中,它的类名是什么?
  • @matino - 是的,它在设置中定义。 get_user_model() 在除 models.py 之外的所有其他文件中都可以正常工作。我的自定义用户模型 AuthUser 是在 MyApp 中定义的(在这个例子中)
  • 我们可以查看您的INSTALLED_APPS 设置吗?
  • 为什么在MyApp的models.py中使用get_user_model()而不是直接引用类名?

标签: django django-models django-users django-1.5


【解决方案1】:

你必须设置,

AUTH_USER_MODEL = "yourapp.CustomUser"

在 settings.py 中。然后get_user_model() 将起作用。有一个干净的documentation available

【讨论】:

  • 已经是了。 get_user_model() 适用于除 models.py 之外的其他文件。
  • 检查您的INSTALLED_APPS 的顺序。包含CustomUser 的应用程序应高于其他应用程序。详细解释在这里,code.djangoproject.com/ticket/19218
【解决方案2】:

我开始认为可能需要一种解决方法 - 以下任何 cmets 在 SomeApp/models.py 中:

from django.contrib.auth.models import User as UserModel
try:
    from django.contrib.auth import get_user_model
except ImportError:  #django <= 1.4 doesn't have get_user_model so define our own
    def get_user_model():
        return UserModel
User = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
...
def SomeModel(models.Model):
    user = models.ForeignKey(User)  # using the name of the model
    def some_method(self, email):
        qs = get_user_model().objects.filter(email=email)  # using function call to get model class 

【讨论】:

  • 嘿@askvictor,你是怎么解决这个问题的?我遇到了同样的问题,但是在运行迁移时,以及在我的应用程序之后安装的包上。
  • @tzenderman - 通过暂停项目解决了这个问题 while :-/ 对于迁移,我有一些相关问题,我通过创建中间迁移以及需要的_by 或 depends_on 解决了这些问题:stackoverflow.com/questions/17711515/…跨度>
【解决方案3】:

确保您的自定义用户模型不是抽象的。

【讨论】:

    【解决方案4】:

    我认为来自 SomeApp 的这种导入是循环导入。这就是为什么docs 中有一个声明来执行诸如 ForeignKey 之类的调用设置属性。

    对于我来说,我在使用 django-filer app 的时候遇到过这个东西。在 github 上有一个 commit 以防止使用 get_user_model() 导入。您可以使用那里的代码作为示例来解决问题。

    这个问题非常棘手,因为当您尝试从 shell 调用 get_user_model() 时 - 它会起作用。

    【讨论】:

      【解决方案5】:

      我刚才遇到了同样的问题,这是我的 2 美分/解决方案。

      如果您想在 models.py 中使用自定义用户模型,您将使用外键 settings.AUTH_USER_MODEL,对于模型方法,您必须使用 get_user_model(),但它必须在 inside方法。由于循环导入,它不会在外面工作。

      from django.conf import settings
      from django.contrib.auth import get_user_model
      
      class Event(models.Model):
      
          recipient = models.ForeignKey(settings.AUTH_USER_MODEL)
          ...
      
          def get_something(self):
      
              User = get_user_model()
              u = User.objects.get(id=...)
              ...
      

      【讨论】:

      • 这是确定的答案。谢谢氟利昂!
      【解决方案6】:

      我觉得很简单。我在递归包含等方面遇到了很多问题...... 好吧,最简单的做法是,当您添加 ForeignKey 时,就是这样写:

      user = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, on_delete=models.CASCADE, verbose_name=_(u"User"))
      

      如果您使用get_user_model,请不要像以前那样使用它。调用

      User = get_user_model()
      

      模块顶部将尝试导入您的User 模型,该模型实际上可能尚未“安装”。 相反,您有多种选择:

      • 在你的模块顶部,写

        User = get_user_model # 那么,你将不得不使用 User() 而不是 User

      • 在有用的地方写上get_user_model()。总是在方法或函数中,从不直接在模型模块体中。

      【讨论】:

      • 这对我有用。我在文件顶部导入 get_user_model() 完全有意义。谢谢
      • 你会如何在声明性代码中处理这个问题?例如,UserSerializer 类具有指定模型的 Meta 类。您不能将 User 模型的定义推迟到执行时间,因为整个定义是在导入时解析的。
      【解决方案7】:

      您正在运行 South 0.8.3 吗?

      确保您至少运行南 0.8.4

      GitHub issue 南放Notes

      【讨论】:

        【解决方案8】:

        Django 文档有答案:https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.get_user_model

        最相关的部分:一般来说,您应该在导入时执行的代码中使用 AUTH_USER_MODEL 设置来引用用户模型。 get_user_model() 仅在 Django 导入所有模型后才有效。

        真正的解决方案是确保只在方法内部使用get_user_model(),这样它就不会在导入时被执行。

        【讨论】:

          猜你喜欢
          • 2013-03-21
          • 2021-04-15
          • 2014-04-05
          • 1970-01-01
          • 2013-06-01
          • 2013-04-20
          • 2013-12-14
          • 2013-02-13
          • 2017-03-31
          相关资源
          最近更新 更多