Django:向 User 类添加属性。 在运行时和 UserManager.create_user 更改它

发布于 2024-07-22 17:53:54 字数 1083 浏览 2 评论 0原文

由于各种复杂的原因[1],我需要向 Django User 类添加额外的属性。

我无法使用配置文件或“继承”方式来执行此操作。 (如 在 Django 中使用自定义字段扩展用户模型 )

所以我一直在做的是将 User 类包含在我的 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 (我假设包含对 User 类的引用)似乎不是我的修补版本。

那么,有谁知道在 UserManager 的情况下这个 self.model 是在哪里设置的? 我是否正确地假设此时代码尚未经过 local_settings,因此我对 User 类的补丁不存在? 是否有更好的地方来修补类?

干杯

菲尔

[1] 满足你的要求 io. 我需要使 User 类使用数据库中不同的现有表,该表具有额外的字段和约束。

更新:为了将来的参考,看起来代理模型是 Django 支持我需要的方式: http ://code.djangoproject.com/ticket/10356

For various complicated reasons[1] I need to add extra properties to the Django User class.

I can't use either Profile nor the "inheritance" way of doing this. (As in Extending the User model with custom fields in Django )

So what I've been doing is including the User class in my local_settings file. And adding the property to it there.

This, perhaps surprisingly, seems to work in many cases. But not when I create a new User from UserManager.create_user(). So I need to patch an alternative to the UserManager.create_user() method. Looking at the source for this (in contrib.auth.models.py) I find that the class it uses to create the User is kept in a property called UserManager.model rather than referenced directly.

The line is this :

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

The problem is that this self.model (which I assume contains a reference to the User class) doesn't seem to be my patched version.

So, does anyone know where this self.model is set-up in the case of UserManager? And whether I'm correct in assuming that at that point the code hasn't gone through local_settings so my patch to the User class isn't there? And if there's a better place to patch the class?

cheers

phil

[1] To satisfy the cur
ious. I need to make the User class use a different and existing table in the database, which has extra fields and constraints.

Update : For future reference, it looks like Proxy Models are the way that Django's going to support what I need : http://code.djangoproject.com/ticket/10356

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

葬花如无物 2024-07-29 17:53:54

拥有特定于站点的用户字段的常用方法是在 settings.py 中指定用户配置文件表。 然后,您可以通过 u.user_profile() 方法检索特定设置。 它在文档中有很好的记录。

The usual way of the having site-specific user fields is to specify a user profile table in your settings.py. You can then retrieve the specific settings via a the u.user_profile() method. It's very well documented in the docs.

同尘 2024-07-29 17:53:54

您可能只需要确保尽早执行替换/添加/猴子补丁(在实际安装身份验证应用程序之前)。 但问题是模型类做了一些元类的事情,这可能会解释为什么 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 类,然后对其进行修补。

这有点脏,但它可能会做您想要的事情想。

You probably just need to make sure that you do the replacement/addition/monkey patch as early as you can (before the auth application is actually installed). The trouble though is that the model classes do some meta-class stuff that'd probably explain why the UserManager has the wrong class - as it will generate the original class, set the UserManager up with that class, then you'll do your stuff and things won't be the same.

So in short be brutal when you replace the class. If you can extend the original class, then replace the original with the extended version:


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

Or if that doesn't work duplicate the User class in your new class and then patch it in.

It's all a bit dirty, but it may do what you want.

箜明 2024-07-29 17:53:54

如果 Django 1.1 beta 对您来说不是太前沿,请尝试代理模型。

If Django 1.1 beta isn't too bleeding edge for you, try proxy models.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文