Django:向用户类添加属性。在运行时更改及UserManager.create_user
由于一些复杂的原因,我需要在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 个回答
通常,要为网站设置特定的用户信息字段,你需要在你的settings.py文件中指定一个用户资料表。这样,你就可以通过u.user_profile()这个方法来获取具体的设置。这个过程在文档中有详细的说明。
你可能只需要确保在认证应用程序真正安装之前,尽早进行替换、添加或者修改。问题在于,模型类会做一些元类的操作,这可能就是为什么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类复制到你的新类里,然后再进行修改。
这方法有点麻烦,但可能能达到你想要的效果。
如果你觉得Django 1.1 beta版本还算可以接受的话,可以试试代理模型。