我想为django.contrib.auth.models.User
模型添加一个方便的/模型方法。自上次检查以来,扩展User模型被认为是不好的做法,因此有哪些最佳实践?
我有一个单独的自定义UserProfile
模型。所有与用户相关的便利方法都应该使用它吗?
我想为django.contrib.auth.models.User
模型添加一个方便的/模型方法。自上次检查以来,扩展User模型被认为是不好的做法,因此有哪些最佳实践?
我有一个单独的自定义UserProfile
模型。所有与用户相关的便利方法都应该使用它吗?
这要看你想向模型中添加什么信息。如果你想添加有关用户的更多信息,则通常建议使用 UserProfile
方法:http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
但是,如果你只想向 User
模型添加自定义方法或管理器,我认为更合理的做法是使用代理模型,如下所示:
from django.contrib.auth.models import User
class UserMethods(User):
def custom_method(self):
pass
class Meta:
proxy=True
代理模型将在与原始模型相同的数据库表上运行,因此非常适合创建自定义方法而不必实际扩展模型。只需将视图中对 User
的任何引用替换为 UserMethods
即可。(当然,您可以通过取消注册 User
模型并在其位置注册代理模型来在管理工具中使用它。)
创建的原始User
模型的任何实例都可以立即通过UserMethods
模型访问,反之亦然。更多信息请参见:http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models
(注意:代理模型需要Django 1.1及以上版本)
如果你想向用户模型添加自定义方法,我建议使用Monkey Patching:
在任意一个app
中创建文件monkey_patching.py
:
#app/monkey_patching.py
from django.contrib.auth.models import User
def get_user_name(self):
if self.first_name or self.last_name:
return self.first_name + " " + self.last_name
return self.username
User.add_to_class("get_user_name",get_user_name)
将其导入到应用程序的__init__.py
文件中。例如:
#app/__init__.py
import monkey_patching
OneToOne
字段,并调用 user_instance.profile
,而不是使用 get_profile()
。 - Eduard Luca2013年更新:
在1.5版中,您可以替换自定义用户模型并添加任何您想要的内容。https://docs.djangoproject.com/en/dev/topics/auth/customizing/#auth-custom-user
我更喜欢在开发的各个项目中使用相同的用户配置文件(UserProfile),并根据每个项目的特定需求对用户进行扩展。因此,常用功能放在UserProfile中,而项目特定功能则放在自定义的用户模型(User)中。迄今为止,我还没有遇到任何子类化User模型会产生不良影响的情况,不知道在Django 1.0+版本中是否仍然存在这样的问题。