Django:向用户类添加属性。在运行时更改及UserManager.create_user

2 投票
3 回答
2980 浏览
提问于 2025-04-15 12:06

由于一些复杂的原因,我需要在Django的用户类中添加额外的属性。

我不能使用Profile或者“继承”的方式来实现这个需求。

所以我现在的做法是把用户类包含在我的local_settings文件中,并在这里添加属性。

这在很多情况下似乎有效,但在我通过UserManager.create_user()创建新用户时就不行了。因此,我需要对UserManager.create_user()方法进行一些修改。查看这个方法的源代码(在contrib.auth.models.py中),我发现它用来创建用户的类保存在一个叫做UserManager.model的属性中,而不是直接引用。

这行代码是:

user = self.model(None, username, '', '', email.strip().lower(), 'placeholder', False, True, False, now, now)

问题是,这个self.model(我猜它包含了对用户类的引用)似乎并不是我修改过的版本。

那么,有人知道在UserManager的情况下,这个self.model是在哪里设置的吗?我是否可以认为在这个时候代码还没有经过local_settings,所以我对用户类的修改没有生效?还有没有更好的地方可以修改这个类?

谢谢!

phil

为了满足好奇心,我需要让用户类使用数据库中一个不同且已存在的表,这个表有额外的字段和约束。

更新:为了将来参考,看起来Django将通过代理模型来支持我需要的功能。

3 个回答

2

通常,要为网站设置特定的用户信息字段,你需要在你的settings.py文件中指定一个用户资料表。这样,你就可以通过u.user_profile()这个方法来获取具体的设置。这个过程在文档中有详细的说明。

2

你可能只需要确保在认证应用程序真正安装之前,尽早进行替换、添加或者修改。问题在于,模型类会做一些元类的操作,这可能就是为什么UserManager的类不对的原因——它会生成原始类,然后用那个类设置UserManager,接着你再做你的修改,结果就不一样了。

所以简单来说,当你替换类的时候要果断。如果可以扩展原来的类,那就用扩展后的版本替换掉原来的:


import django.contrib.auth.models
from django.contrib.auth.models import User as OriginalUser

class User(OriginalUser):
    pass # add your extra fields etc

# then patch the module with your new version
django.contrib.auth.models.User = User

如果这样不行,那就把User类复制到你的新类里,然后再进行修改。

这方法有点麻烦,但可能能达到你想要的效果。

2

如果你觉得Django 1.1 beta版本还算可以接受的话,可以试试代理模型。

撰写回答