如何为Django Auth用户模型添加便捷方法?

22

我想为django.contrib.auth.models.User模型添加一个方便的/模型方法。自上次检查以来,扩展User模型被认为是不好的做法,因此有哪些最佳实践?

我有一个单独的自定义UserProfile模型。所有与用户相关的便利方法都应该使用它吗?

5个回答

30

这要看你想向模型中添加什么信息。如果你想添加有关用户的更多信息,则通常建议使用 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及以上版本)


好的,你说得对!完全忘记了代理模型。我正在运行1.1版本,但思维还停留在1.0时代。 - Soviut
14
有没有简单的方法将request.user的类型更改为代理类型?这是否必要,还是我可以直接在request.user上调用代理方法? - slacy
3
我和 @slacy 一样有同样的疑问,在这个答案中找到了解决方法:https://stackoverflow.com/a/11526049/188614。基本上,你需要继承 django.contrib.auth.backends.ModelBackend,然后在 get_user 方法中返回 UserMethods,并将其设置为 AUTHENTICATION_BACKENDS。 - Diego Ponciano
这个 Django 文档的链接已经失效了,有人知道新的 URL 吗? - CoderGuy123

14

如果你想向用户模型添加自定义方法,我建议使用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

4
是的。如果您的用户模型已经附带了.get_profile()函数,那么就无需更改基础结构。

1
+1,扩展用户模型仍然不被推荐,而且所有与个人资料相关的管道已经准备就绪,可以利用。 - Ryan Duffield
你可以在个人资料模型上添加一个 OneToOne 字段,并调用 user_instance.profile,而不是使用 get_profile() - Eduard Luca

3

-1

我更喜欢在开发的各个项目中使用相同的用户配置文件(UserProfile),并根据每个项目的特定需求对用户进行扩展。因此,常用功能放在UserProfile中,而项目特定功能则放在自定义的用户模型(User)中。迄今为止,我还没有遇到任何子类化User模型会产生不良影响的情况,不知道在Django 1.0+版本中是否仍然存在这样的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接