在Django模型中如何正确添加自定义实例属性?
我想给Django模型的实例添加一些自定义属性。这些属性不需要存储在数据库里。在其他类里,这些属性通常会通过__init__
方法来初始化。
我已经想到了三种不同的方法来实现这个目标,但都不是特别满意。我在想有没有更好、更符合Python或Django风格的方法呢?
重写
__init__
方法:语法有点复杂,但可以实现。from django.db.models import Model class Foo(Model): def __init__(self, *args, **kwargs): super(Model, self).__init__(*args, **kwargs) self.bar = 1
使用Django的
post_init
信号:这样做会把类的代码放到类定义之外,这样看起来不太容易理解。from django.dispatch import receiver from django.db.models.signals import post_init @receiver(post_init, sender=Foo) def user_init(sender, instance, *args, **kwargs): instance.bar = 1
用实例方法代替属性:默认情况下抛出一个通用异常,这样的行为有点让人不安。
class Foo(Model): def bar(self): try: return self.bar except: self.bar = 1 return self.bar
在这三种选择中,我觉得第一种是最不糟糕的。你觉得呢?有没有其他的选择?
2 个回答
9
我会使用Python中的属性装饰器
class Foo(Model):
@property
def bar(self):
if not hasattr(self, '_bar'):
self._bar = 1
return self._bar
这样你就可以像访问属性一样来使用它,而不是用()来调用一个函数
你甚至可以更简单一点,把备用方案直接内置,而不是单独存储
class Foo(Model):
@property
def bar(self):
return getattr(self, '_bar', 1)
4
重写 __init__
是正确的方法。