我想将自定义属性添加到Django模型的实例中。这些属性不应存储在数据库中。在任何其他类中,属性将仅由__init__
方法初始化。
我已经可以看到三种不同的方法,而且没有一种方法是完全令人满意的。我想知道是否有更好/更多的pythonic / djangoist方法来做它?
Override __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
在这三个选择中,第一个看起来对我来说是最差的。你怎么看?还有其他选择吗?
答案 0 :(得分:7)
我会使用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)
答案 1 :(得分:3)
覆盖__init__
是正确的方法。