【发布时间】:2018-06-27 02:49:42
【问题描述】:
目前我有以下 Django 模型
class TestUser(models.Model):
name = models.CharField(max_length=250)
email = models.CharField(max_length=250)
...
class Meta:
db_table = 'temp_user'
我有以下方法。
def print_name(self):
return self.name
我想将此方法作为属性添加到TempUser 模型。我知道这可以通过将方法放在TempUser 类和用户@property 中来完成。但我想动态地做。
我在 python shell 中试过这个。
In [10]: TempUser.print_name = property(print_name)
In [11]: TempUser.print_name
Out[11]: <property at 0x7efc374e7c58>
In [12]: user = TempUser.objects.get(pk=1)
In [13]: user.print_name
Out[13]: u'Test User'
但是一旦我退出 shell,我就失去了属性。有没有办法永久添加属性。
【问题讨论】:
-
为什么需要这样做?您还需要动态添加哪些其他属性到您的模型中?
-
您到底想完成什么?属性的用处有限,因为您无法查询它们(因为它们实际上并不存在于数据库中)——SQLAlchemy 有一个
hybrid_property可以让您对属性进行查询。使用 Django 实现类似功能的一种方法是通过 annotating 默认查询集通过向模型管理器的get_queryset添加注释来实现类似的功能。这可能适合你的情况。性能影响确实适用。 -
@Pattu:你必须更清楚你真正想要完成的事情。这些属性是否都是
TestUser列的简单表达式,或者它们是否可以包含任意 Python 代码?它们是正面的吗?它们会被(可能是恶意的)用户创建/删除吗?为什么这个用户不能只编辑models.py文件? -
但这解决了什么问题?我强烈建议避免这种情况。像这样动态地将属性/属性添加到实例上几乎是无用的,并且可以说对您的应用程序设计是危险的。如果要使用属性,请使用
@property方法装饰器来实现它们。在很多情况下,您的模型会被序列化或从数据库重新加载,在这种情况下,您对不在数据库中的对象所做的任何修改都会丢失,即使它看起来您可能正在传递直接的对象。 -
@Pattu:为什么不能将它们放入
models.py?
标签: python django properties metaclass