【问题标题】:Add class method after definition in a Python / Django model在 Python / Django 模型中定义后添加类方法
【发布时间】:2014-07-24 19:06:57
【问题描述】:

我正在使用 Django,我通过以下方式导入用户模型:

from django.contrib.auth.models import User, Group, Permission

但现在我想在User 模型类中添加一些类方法。

所以我的一般问题来了:我们可以在定义类之后添加类方法吗?

例如:

class A:
    value = 123

def myfunc(self):
    return self.value

我想让 myfunc 成为 A 类的成员函数,怎么可能?请帮忙。

【问题讨论】:

  • 这通常就像A.myfunc = myfunc 一样简单,但我不确定 Django 对元类的使用是否会干扰这一点。
  • 为什么不扩展/子类化用户类并添加您的方法。为什么要在定义类之后添加方法?
  • 不是骗子。这是关于向类添加新方法,而不是类的单个实例。
  • 哦,谢谢@user2357112,我一直在尝试直接定义一个,但没有注意到我可以先定义它然后将其分配给类。
  • 该问题并非完全重复,但答案也涵盖了您的问题。请注意,“类方法”在 Python 中有一个 specific meaning,您可能不是这个意思。

标签: python django django-models


【解决方案1】:

既然你在谈论 Django User 模型,you should create your own model, extending the User。为此,你只需要创建一个与User 模型有OneToOne 关系的模型:,你应该创建一个新用户模型,通过扩展AbstractUser:

from django.contrib.auth.models import AbstractUser

class MyUserModel(AbstractUser):
    # AbstractUser has already every fields needed: username, password, is_active...
    def myfunc(self):
        # Just a dummy working example
        return "My Username in uppercase: %s" % self.username.upper()

并将AUTH_USER_MODEL = "yourapp.MyUserModel" 放入settings.py

然后,您可以像使用User 一样使用这个新用户模型:它具有与User 相同的方法(例如create_usercheck_password...),并且您可以访问@ 987654337@ 和user.myfunc(),其中user 是常规MyUserModel 实例(从request.user 或ORM 获取)。这更符合框架组织,并允许您根据需要向User 添加更多字段。


旁注:正如@Daniel Roseman 在 cmets 中指出的那样,您应该 really extend the AbstractUser model now(从 Django 1.6 开始)而不是创建 UserProfile “代理”。

相关问题:

【讨论】:

  • 不建议再创建 UserProfile 模型。正如您在第一句话中暗示的那样,OP 实际上应该扩展用户,最好通过继承 AbstractUser 并将 settings.AUTH_USER_MODEL 指向新类。
  • 那么,我可以这样理解吗:由于我只是想添加一个方法,并且不想影响数据字段,所以我最好不要扩展 User 模型而只是添加一个方法吗? @丹尼尔罗斯曼
  • @DanielRoseman Cleary,是的。对不起这个老 Django
  • @fish_ball 不,您应该按照 Maxime 所示扩展模型。另一种方法是子类化具体的 auth.User 模型,但在 Meta 类中设置 proxy=True:您仍然需要将 AUTH_USER_MODEL 设置为新类,因此这些方法之间没有太大区别。
【解决方案2】:

配置文件很好,它会工作并且没有问题。在 Django ORM 中实际意味着的一个选项是代理模型。在代理模型中,您可以拥有父模型的所有字段并添加您的自定义方法或管理器,而无需更改父模型。

from django.contrib.auth.models import User

class MyUser(User):
    class Meta:
        proxy = True


    def my_method(self):
        return self.name

【讨论】:

    【解决方案3】:

    您可以按照 user2357112 的建议通过赋值添加类方法。

    class A(object):
        value = 123
    
    def myfunc(cls):
        return cls.value
    
    A.myfunc = classmethod(myfunc)
    
    print A.myfunc()
    > 123
    

    对于 Django 模型,您可能希望使用自定义 Manager 来处理所有用户的功能,而不是类方法。但是如果没有更多信息,我不能说更多。

    【讨论】:

      猜你喜欢
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 1970-01-01
      • 2011-01-13
      • 2017-12-27
      • 2013-09-09
      • 1970-01-01
      相关资源
      最近更新 更多